HDU4565 && 2013年长沙邀请赛A题
部分转自http://blog.csdn.net/crazy______/article/details/9021169
#include<cstdio> using namespace std; __int64 A[3][3],s[3][3],tmp[3][3]; void fun(__int64 n,__int64 m) { __int64 i,j,k; for(i=1;i<=2;i++) for(j=1;j<=2;j++) { s[i][j]=A[i][j]; } --n; while(n) { if(n&1) { for(i=1;i<=2;i++) for(j=1;j<=2;j++) { tmp[i][j]=A[i][j]; A[i][j]=0; } for(i=1;i<=2;i++) for(j=1;j<=2;j++) for(k=1;k<=2;k++) { A[i][j]=((A[i][j]+tmp[i][k]*s[k][j])%m+m)%m; } } for(i=1;i<=2;i++) for(j=1;j<=2;j++) { tmp[i][j]=s[i][j]; s[i][j]=0; } for(i=1;i<=2;i++) for(j=1;j<=2;j++) for(k=1;k<=2;k++) { s[i][j]=((s[i][j]+tmp[i][k]*tmp[k][j])%m+m)%m; } n>>=1; } } int main() { __int64 a,b,n,m; __int64 i,j; while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&m)==4) { if(n==1) { printf("%I64d\n",2*a%m); continue; } A[1][1]=2*a; A[1][2]=b-a*a; A[2][1]=1; A[2][2]=0; fun(n-1,m); printf("%I64d\n",((A[1][1]*2*a+A[1][2]*2)%m+m)%m); } return 0; }