http://www.lydsy.com/JudgeOnline/problem.php?id=3240
Description
婷婷是個喜歡矩陣的小朋友,有一天她想用電腦生成一個巨大的n行m列的矩陣(你不用擔心她如何存儲)。她生成的這個矩陣滿足一個神奇的性質:若用F[i][j]來表示矩陣中第i行第j列的元素,則F[i][j]滿足下面的遞推式:
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)
遞推式中a,b,c,d都是給定的常數。
現在婷婷想知道F[n][m]的值是多少,請你幫助她。由於最終結果可能很大,你只需要輸出F[n][m]除以1,000,000,007的餘數。
n,m太大,模(mod-2) 費馬小定理。
推通項討論。。噁心死人。MOD更噁心死。
另外:貼吧大神說矩陣也滿足費馬小定理?(亟待驗證)
http://tieba.baidu.com/p/2472273208
/*直接推通項。矩陣不好做的。*/
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const LL MOD=1000000007LL;
void getMOD(char *a,LL &A,bool p){
LL mod=MOD-p;
int len=strlen(a);
for (int i=0;i<len;++i)
A=((A<<3)+(A<<1)+a[i]-'0')%mod;
A=(A+mod)%mod;
}
LL power(LL a,LL b){
LL res=1;
for (;b;a=a*a%MOD,b>>=1)
if (b&1) (res*=a)%=MOD;
return res;
}
char TN[1000050],TM[1000050];
LL n,m,a,b,c,d;
LL Fn1,Fnm;
int main(){
scanf("%s %s %lld %lld %lld %lld",TN,TM,&a,&b,&c,&d);
if (a==1&&c==1){
getMOD(TN,n,0),getMOD(TM,m,0);
Fnm=((((n-1+MOD)%MOD)*((m-1+MOD)%MOD)%MOD)*(b*c%MOD)%MOD+(((n-1+MOD)%MOD)*d)%MOD+(((m-1+MOD)%MOD)*b)%MOD+1+MOD)%MOD;
printf("%lld\n",Fnm);
return 0;
}
LL A,B;
if (a==1){
getMOD(TM,m,0);
A=c;
B=(((m-1+MOD)%MOD)*(b*c%MOD)%MOD+d)%MOD;
}
if (a!=1){
getMOD(TM,m,1);
A=c*power(a,(m-1+MOD-1)%(MOD-1))%MOD;
B=((((b*c%MOD)*power((a-1+MOD)%MOD,MOD-2))%MOD*(power(a,(m-1+MOD-1)%(MOD-1))-1+MOD)%MOD)%MOD+d)%MOD;
}
//A!=1
getMOD(TN,n,1);
Fn1=(power(A,(n-1+MOD-1)%(MOD-1))+((power(A,(n-1+MOD-1)%(MOD-1))-1+MOD)%MOD*B)%MOD*power((A-1+MOD)%MOD,MOD-2)%MOD)%MOD;
if (a==1) Fnm=(Fn1+((m-1+MOD)%MOD*b)%MOD)%MOD;
if (a!=1) Fnm=((power(a,(m-1+MOD-1)%(MOD-1))*Fn1)%MOD+((power(a,(m-1+MOD-1)%(MOD-1))-1+MOD)%MOD*b)%MOD*power((a-1+MOD)%MOD,MOD-2)%MOD)%MOD;
printf("%lld\n",Fnm);
}