题目大意:
一个n行m列的矩阵,
F[1][1]=1
F[i,j]=a*F[i][j-1]+b (j!=1)
F[i,1]=c*F[i-1][m]+d (i!=1)
其中:1<=n,m<=10^1000000,1<=a,b,c,d<=10^9
输出F[n][m]除以1,000,000,007的余数
如果用快速幂的话,需要把十进制数n,m转化为二进制,而n,m要用字符串来存储且极大,所以会TLE
这里使用十进制快速幂
另外,构造的矩阵只能用到第一列,因此把它们化简到两个元素即可,可以减小时间常数
具体见代码
#include<stdio.h> #include<stdlib.h> #include<string.h> #define mod 1000000007 typedef long long LL; char sn[1000005],sm[1000005]; struct juzhen { LL v1,v2;//矩阵化简:对于s[1][2]==0的矩阵,只保留s[1][1],s[2][1];不需要Z矩阵 }; juzhen I;//单位矩阵 juzhen cheng(juzhen a,juzhen b) { juzhen res; res.v1=(a.v1*b.v1)%mod; res.v2=(a.v2*b.v1+b.v2)%mod; return res; } juzhen ksm(juzhen a,int n) { juzhen res; if(n==0) return I; if(n==1) return a; res=ksm(a,n/2); res=cheng(res,res); if(n%2==1) res=cheng(res,a); return res; } juzhen T_ksm(juzhen a,char s[],int len)//十进制快速幂:O(10*lg(n)) { juzhen res=I,t=a; for(;len>=0;len--) { res=cheng(res,ksm(t,s[len]-'0')); t=ksm(t,10); } return res; } int main() { juzhen A,B,C; int i,Ln,Lm; scanf("%s%s",sn,sm); Ln=strlen(sn)-1; sn[Ln]--;//n-- for(i=Ln;sn[i]<'0';i--) { sn[i]+=10; sn[i-1]--; } Lm=strlen(sm)-1; sm[Lm]--;//m-- for(i=Lm;sm[i]<'0';i--) { sm[i]+=10; sm[i-1]--; } scanf("%lld%lld%lld%lld",&A.v1,&A.v2,&B.v1,&B.v2); I.v1=1; I.v2=0; A=T_ksm(A,sm,Lm); C=cheng(B,A); C=T_ksm(C,sn,Ln); C=cheng(A,C); printf("%lld",(C.v1+C.v2)%mod); return 0; }