http://acm.hdu.edu.cn/showproblem.php?pid=1588 #include<iostream> #include<map> using namespace std; #define N 4 #define FF(i,n) for(int i=0;i<n;i++) int len,mod; struct Matrix_Cal{ __int64 mat[N][N]; }e,init,tp1,tp2,tp3; Matrix_Cal operator+(Matrix_Cal a ,Matrix_Cal b){ Matrix_Cal c; FF(i,len)FF(j,len) c.mat[i][j]=a.mat[i][j]+b.mat[i][j]; return c; } Matrix_Cal operator*(Matrix_Cal a , Matrix_Cal b){ Matrix_Cal c; int i,j,k; FF(i,len)FF(j,len) c.mat[i][j] = 0; FF(i,len)FF(k,len) if(a.mat[i][k])FF(j,len) if(b.mat[k][j]) c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod; return c; } Matrix_Cal operator^(Matrix_Cal a,int b){ Matrix_Cal c=e, q=a; for(;b;b>>=1){ if(b&1) c=c*q; q=q*q; } return c; } Matrix_Cal Matrix_Sum(Matrix_Cal a,int b){ if(b==1) return a; if(b&1) return Matrix_Sum(a,b-1)+(a^b); else return ((a^(b>>1))+e)*Matrix_Sum(a,b>>1); } int main(void){ int i,j,k,b,n; while(~scanf("%d%d%d%d",&k,&b,&n,&mod)){ FF(i,N)FF(j,N) e.mat[i][j]=(i==j); memset(init.mat,0,sizeof(init.mat)); init.mat[0][0]=init.mat[0][1]=init.mat[0][2]=1; init.mat[1][0]=init.mat[1][3]=1; init.mat[2][2]=init.mat[3][3]=1; len=2; tp1=init^b; tp3=init^k; FF(i,2) FF(j,2) init.mat[i][j]=tp3.mat[i][j]; len=4; tp2=Matrix_Sum(init,n-1); len=2; tp1=tp1+tp1*tp2; printf("%d/n",tp1.mat[0][1]%mod); } }