HDU 5667 Sequence(构造矩阵+费马小定理)

来源:互联网 发布:erp系统属于数据库 编辑:程序博客网 时间:2024/06/13 11:03

传送门

手动写出前几项发现每一项都是a^b的多少次方,而且正好满足递推式Fn=c*Fn-1+Fn-2+1

那么可以用矩阵快速幂来求这个系数ans。

注意最后答案是a^b的ans次方,ans是一个很大的数,而根据费马小定理,A ^ B % C  =  A^  (B%(C-1))   %C

所以我们在求ans的时候应该取的是MOD-1,在计算最后答案是取的是MOD。

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;typedef long long LL;const int N = 3;int MOD;LL quickpow(LL m,LL n){    LL b=1;    m%=MOD;    while(n>0)    {        if(n&1)b=(b*m)%MOD;        n=n>>1;        m=(m*m)%MOD;    }return b;}struct Matrix{    LL m[N][N];};Matrix I = {//I主对角线是1       1,0,0,       0,1,0,       0,0,1};Matrix multi(Matrix a,Matrix b)//矩阵乘法{    Matrix c;    for(int i=0;i<N;i++)    {        for(int j=0;j<N;j++)        {            c.m[i][j] = 0;            for(int k=0;k<N;k++)                c.m[i][j] += a.m[i][k] * b.m[k][j] % MOD;            c.m[i][j] %= MOD;        }    }    return c;}Matrix power(Matrix A,LL k)//矩阵A的k次幂(快速幂){    Matrix ans = I,p = A;    while(k)    {        if(k&1)        {            ans = multi(ans,p);            k--;        }        k >>= 1;        p = multi(p,p);    }    return ans;}int main(){    int t;    LL n,a,b,c;    scanf("%d",&t);    while(t--)    {scanf("%lld%lld%lld%lld%d",&n,&a,&b,&c,&MOD);        Matrix A = {       c%MOD,1,1,       1,0,0,       0,0,1        };    int aa=quickpow(a,b);    LL ans=1;    if(n>1)    {        MOD--;         Matrix ansm=power(A,n-2);        ans=((ansm.m[0][0]*1)%MOD+(ansm.m[0][2]*1)%MOD)%MOD;        ans=quickpow(aa,ans%(MOD++));    }        printf("%lld\n",ans);    }    return 0;}


阅读全文
0 0