zoukankan      html  css  js  c++  java
  • HDU A Simple Math Problem (矩阵快速幂)

    题面

    Problem Description
    Lele now is thinking about a simple function f(x).

    If x < 10 f(x) = x.
    If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
    And ai(0<=i<=9) can only be 0 or 1 .

    Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.

    Input
    The problem contains mutiple test cases.Please process to the end of file. In each case, there will be two lines. In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 ) In the second line , there are ten integers represent a0 ~ a9.

    Output
    For each case, output f(k) % m in one line.

    Sample Input
    10 9999
    1 1 1 1 1 1 1 1 1 1
    20 500
    1 0 1 0 1 0 1 0 1 0

    Sample Output
    45
    104

    思路

    直接看就是快速幂,我们关注一下这个2*1e9的数据量,这个数据量的话,复杂度肯定要降到log级别的,所以快速幂并木有错误。那么重点还是构造矩阵,我们让第一列是题目给的递推式子,其余为单位偏移作用。做n-9次的快速幂后和f1-f9去相乘就好啦。那么有几个细节注意,矩阵乘法的时候要取两遍的mod,然后最后的矩阵乘法不要写反,矩阵的相乘并不满足交换律,还有就是数组不要开小,会re。这些矩阵快速幂的题目都一个套路,我们真正要做的就是去把题目中隐含的或者直接给的递推式求出来,然后构造相应的辅助矩阵,最后完成快速幂就好。

    代码实现

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int inf =0x3f3f3f3f;
    const int maxn=11;
    struct Matrix {
        int maze[maxn][maxn];
        Matrix () {
            memset (maze,0,sizeof (maze));
        }
    };
    int n,mod;
    Matrix mul (Matrix a,Matrix b) {
        Matrix ans;
        for (int i=1;i<=10;i++) 
         for (int j=1;j<=10;j++){
           for (int k=1;k<=10;k++) 
               ans.maze[i][j]=(ans.maze[i][j]+(a.maze[i][k]*b.maze[k][j])%mod)%mod;
           }
           return ans;
    }
    Matrix fats_pow (Matrix a,int p) {
        Matrix ans;
        for (int i=1;i<=10;i++) ans.maze[i][i]=1;
        while (p) {
            if (p&1) ans=mul (ans,a);
            a=mul(a,a);
            p>>=1;
        }
        return ans;
    }
    int main () { 
        while (cin>>n>>mod) {
            Matrix fz;
            for (int i=1;i<=10;i++) cin>>fz.maze[i][1];
            for (int i=1;i<=9;i++) fz.maze[i][i+1]=1;
            if (n<10) {
                cout<<n%mod<<endl;
                continue;
            } 
            else {
                Matrix k;
                for (int i=1;i<=10;i++) k.maze[1][i]=10-i;
                fz=fats_pow (fz,n-9);
                k=mul (k,fz);
                cout<<k.maze[1][1]%mod<<endl;
            }
        }   
        return 0;
    }
    
  • 相关阅读:
    contentSize、contentInset和contentOffset区别 分类: iphone开发
    iOS设计模式——Category
    如何更好地限制一个UITextField的输入长度
    UIApplication sharedApplication详细解释-IOS
    IOS --- 对象归档
    iOS 数据持久化之使用NSUserDefaults存储数据
    判断素数 一个数的约数 一个整数的幂次约分
    埃氏筛法
    双六(扩展欧几里得算法)
    矩阵快速幂 模板
  • 原文地址:https://www.cnblogs.com/hhlya/p/13288649.html
Copyright © 2011-2022 走看看