LightOJ 1070 Algebraic Problem (推導+矩陣高速冪)
阿新 • • 發佈:2017-06-06
思路 註意 結果 string blog font log 得到 code
題目鏈接:
problem=1070">LightOJ 1070 Algebraic Problem
題意:已知a+b和ab的值求a^n+b^n。結果模2^64。
思路:
1.找遞推式
得到遞推式之後就是矩陣高速冪了
註意:模2^64,定義成unsigned long long 類型,由於無符號類型超過最大範圍的數與該數%最大範圍 的效果是一樣的。
AC代碼:
#include<stdio.h> #include<string.h> #define LL unsigned long long struct Matrix { LL m[10][10]; }; LL n; Matrix geti(LL n) { LL i; Matrix b; memset(b.m,0,sizeof b.m); for(i=0;i<2;i++) b.m[i][i]=1; return b; } Matrix matrixmul(Matrix a,Matrix b) { LL i,j,k; Matrix c; for(i=0;i<2;i++) { for(j=0;j<2;j++) { c.m[i][j]=0.0; for(k=0;k<2;k++) { c.m[i][j]+=(a.m[i][k]*b.m[k][j]); } } } return c; } Matrix quickpow(Matrix a,LL p) { Matrix m=a; Matrix b=geti(n); while(p) { if(p%2) b=matrixmul(b,m); p/=2; m=matrixmul(m,m); } return b; } int main() { LL t; LL p,q; int cas=1; Matrix pp,init,ans; //printf("%llu\n",kmod); scanf("%llu",&t); while(t--) { scanf("%llu %llu %llu",&p,&q,&n); memset(pp.m,0,sizeof pp); pp.m[0][0]=p; pp.m[0][1]=1; pp.m[1][0]=-q; pp.m[1][1]=0; init.m[0][0]=p; init.m[0][1]=2; init.m[1][0]=0; init.m[1][1]=0; printf("Case %d: ",cas++); if(n==0){ printf("%llu\n",init.m[0][1]); } else if(n==1){ printf("%llu\n",init.m[0][0]); } else { ans=quickpow(pp,n-1); ans=matrixmul(init,ans); printf("%llu\n",ans.m[0][0]); } } return 0; } /* */
LightOJ 1070 Algebraic Problem (推導+矩陣高速冪)