HDU - 1757 A Simple Math Problem (矩阵快速幂)

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. 
OutputFor 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

思路:
矩阵太大,用5*5的代为表达吧~

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100086;
const int maxm = 100086;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
int mod;
const double eps = 1e-6;
const double pi = acos(-1);

struct Matrix{
    int mp[15][15];
};
Matrix mul(Matrix a,Matrix b,int n){
    Matrix ans;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            ans.mp[i][j]=0;
            for(int k=1;k<=n;k++){
                ans.mp[i][j]+=a.mp[i][k]*b.mp[k][j];
            }
            ans.mp[i][j]%=mod;
        }
    }
    return ans;
}

Matrix q_pow(Matrix a,int b,int n){
    Matrix ans;
    memset(ans.mp,0,sizeof(ans.mp));
    for(int i=1;i<=n;i++){
        ans.mp[i][i]=1;
    }
    while (b){
        if(b&1){
            ans=mul(ans,a,n);
        }
        b>>=1;
        a=mul(a,a,n);
    }
    return ans;
}

int main()
{
//    ios::sync_with_stdio(false);
//    freopen("in.txt","r",stdin);

    Matrix exa;
    int n;
    while(scanf("%d%d",&n,&mod)!=EOF){
        memset(exa.mp,0,sizeof(exa.mp));
        for(int i=1;i<=10;i++){
            scanf("%d",&exa.mp[1][i]);
        }
        if(n<10){printf("%d\n",n);continue;}
        for(int i=2;i<=10;i++){
            exa.mp[i][i-1]=1;
        }
        exa = q_pow(exa,n-9,10);
        ll ans=0;
        for(int i=1;i<=10;i++){
            ans+=(10-i)*exa.mp[1][i];//注意这里是10-i
            ans%=mod;
        }
        printf("%lld\n",ans);
    }


    return 0;
}
View Code

 

 


posted @ 2019-05-17 11:53  断腿三郎  阅读(250)  评论(0编辑  收藏  举报