ACM-数论-矩阵快速幂 解斐波那契数列Yet another Number Sequence(UVA)

题意:就是求某斐波那契数列的第n个数值,同时要进行取余运算,避免爆数据。

value of n ranges in [0, 1000000000] 
value of m ranges in [1, 4]

input

4
0 1 11 3
0 1 42 4
0 1 22 4
0 1 21 4

output

89
4296
7711
946

矩阵快速幂的原理
ACM-数论-矩阵快速幂 解斐波那契数列Yet another Number Sequence(UVA)_第1张图片
详情点链接这里介绍比较全,我主要讲一下这题的我踩的坑

这里的
1.res.v[i][j]%=mod;//这里的mod必须是题目中m决定的!!!
不是1e9+7!!!!
2.if(n==0)printf("%lld\n",b);
3.a.v[0][0]=1;a.v[1][0]=1;a.v[0][1]=1;a.v[1][1]=0;
fn=ans.v[0][0]*f1+ans.v[0][1]*f0

矩阵快速幂模板:

struct matrix{
    ll v[2][2];
    matrix(){
        memset(v,0,sizeof(v));
    }
    matrix operator *(matrix &t){
        matrix res;
        memset(res.v,0,sizeof(res.v));
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                for(int k=0;k<2;k++){
                    res.v[i][j]+=(v[i][k]%mod*t.v[k][j]%mod)%mod;
                    res.v[i][j]%=mod;
                } 
        return res;         
    }
};
matrix power(matrix a,int b){
    matrix ans;
    memset(ans.v,0,sizeof(ans.v));
    ans.v[0][0]=1;
    ans.v[1][1]=1;
    while(b>0){
        if(b&1)ans=ans*a;
        b=b>>1;
        a=a*a;
    }
    return ans;
}

矩阵快速幂引用

matrix ans,a; 
    for(int i=1;i<=t;i++){
        scanf("%lld %lld %d %d",&b,&c,&n,&m);
        if(n==0)printf("%lld\n",b);
        else{
            a.v[0][0]=1;a.v[0][1]=1;
            a.v[1][0]=1;a.v[1][1]=0;
            mod=1;
            while(m--)mod*=10; //题意的mod,包括用于矩阵的*操作
            ans=power(a,n-1);
            ll sum=((ans.v[0][0]*c)%mod+(ans.v[0][1]*b)%mod)%mod;                                                                                                                                                                                                                                                                                                              
            printf("%lld\n",sum);
        }
    }

欢迎各位指正不足之处!顺便点个赞嘛~

你可能感兴趣的:(算法题解)