Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1706 Accepted Submission(s): 741
题目要求求出f(g(i))的总和,i是0~n-1
代码中详细思路+注释
/*f(g(i))=f(k*i+b) 令f[n]=A;//A是矩阵,A的某个元素是F[n] 若i=0~n-1,则sum(f(k*i+b)) =A^b+A^(k+b)+A^(2k+b)+A^(3k+b)+...+A^((n-1)k+b) =A^b+A^b(A^k+A^2k+A^3k+A^4k+...+A^(n-1)k) 将A^k看成一个新的矩阵B,则原式: =A^b+A^b(B^1+B^2+B^3+...+B^(n-1));//A^b,A^k用矩阵快速幂求出,括号中的用二分矩阵可求 所谓二分矩阵:A^1+A^2+A^3+A^4+A^5+A^6=(A^1+A^2+A^3)+A^3(A^1+A^2+A^3) */ #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<iomanip> #define INF 99999999 using namespace std; const int MAX=2; __int64 array[MAX][MAX],sum[MAX][MAX],temp[MAX][MAX],ans[MAX][MAX]; //array相当于A,sum记录每次幂乘后的矩阵,temp是临时矩阵,ans是B^1+B^2+B^3+...+B^n void MatrixInit(__int64 a[MAX][MAX],bool flag){//初始化矩阵 for(int i=0;i<MAX;++i){ for(int j=0;j<MAX;++j){ if(flag)a[i][j]=array[i][j];//a=A else a[i][j]=(i == j);//a=1 } } } void MatrixAdd(__int64 a[MAX][MAX],__int64 b[MAX][MAX],int &mod){//矩阵相加 for(int i=0;i<MAX;++i){//a=a+b for(int j=0;j<MAX;++j){ a[i][j]=(a[i][j]+b[i][j])%mod; } } } void MatrixMult(__int64 a[MAX][MAX],__int64 b[MAX][MAX],int &mod){//矩阵相乘 __int64 c[MAX][MAX]={0}; for(int i=0;i<MAX;++i){//a=a*b for(int j=0;j<MAX;++j){ for(int k=0;k<MAX;++k){ c[i][j]+=a[i][k]*b[k][j]; } } } for(int i=0;i<MAX;++i){ for(int j=0;j<MAX;++j)a[i][j]=c[i][j]%mod; } } void MatrixPow(int k,int &mod){//矩阵幂乘,sum=A^k MatrixInit(sum,0);//sum=1 MatrixInit(temp,1);//temp=A while(k){ if(k&1)MatrixMult(sum,temp,mod); MatrixMult(temp,temp,mod); k>>=1; } } void MatrixSum(int k,int &mod){//矩阵求和 if(k == 1){MatrixInit(ans,1);return;} MatrixSum(k/2,mod); MatrixPow((k+1)/2,mod); if(k&1){//k为奇数则A+(A+A^m)*(A+A^2+A^3...),m=(k+1)/2 MatrixInit(temp,1);//temp=A MatrixAdd(sum,temp,mod);//sum=A+A^m MatrixMult(ans,sum,mod);//ans=sum*ans MatrixAdd(ans,temp,mod);//ans=A+ans } else{//k为偶数则(1+A^m)*(A+A^2+A^3...),m=(k+1)/2 MatrixInit(temp,0);//temp=1 MatrixAdd(temp,sum,mod);//temp=1+A^m MatrixMult(ans,temp,mod);//ans=ans*temp; } } int main(){ int k,b,n,m; while(scanf("%d%d%d%d",&k,&b,&n,&m)!=EOF){ array[0][0]=array[0][1]=array[1][0]=1; array[1][1]=0; MatrixPow(k,m);//求A^k MatrixInit(array,0); MatrixMult(array,sum,m);//将array构造成B,即A^k MatrixSum(n-1,m);//求矩阵和 array[0][0]=array[0][1]=array[1][0]=1; array[1][1]=0; MatrixPow(b,m);//求A^b; MatrixMult(ans,sum,m);//求A^b*ans MatrixAdd(ans,sum,m);//求A^b+A^b+ans printf("%I64d\n",ans[1][0]); } return 0; }