LightOJ 1070 Algebraic Problem (推导+矩阵高速幂)
Posted yutingliuyl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LightOJ 1070 Algebraic Problem (推导+矩阵高速幂)相关的知识,希望对你有一定的参考价值。
题目链接:php?
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 (推导+矩阵高速幂)的主要内容,如果未能解决你的问题,请参考以下文章
LightOJ 1070 - Algebraic Problem 推导+矩阵快速幂
Algebraic Data Type 及其在 Haskell 和 Scala 中的表现