hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***
分析:假设g(g(g(n)))=g(x),x可能非常大,但是由于mod 10^9+7,所以可以求出x的循环节
求出x的循环节后,假设g(g(g(n)))=g(x)=g(g(y)),即x=g(y),y也可能非常大,但是由x的循环节可以求出y的循环节
所以最终结果只要进行矩阵快速幂即可求出
循环节
1 #include<stdio.h> 2 3 const long long MOD=222222224;//第一次是MOD=1000000007 找出循环节是222222224 4 //第二次是MOD=222222224,找出循环节183120 5 int main() 6 { 7 long long a,b; 8 a=1; 9 b=3; 10 for(int i=1;;i++) 11 { 12 if(a==0&&b==1) 13 { 14 printf("%d\n",i); 15 break; 16 } 17 long long c=3*b+a; 18 c%=MOD; 19 a=b; 20 b=c; 21 } 22 return 0; 23 }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #define INF 99999999 11 using namespace std; 12 13 const int mod1=1000000007;//求结果的循环节 14 const int mod2=222222224;//第1层的循环节,假设g(g(g(n)))=g(x),即mod2是x的循环节 15 const int mod3=183120;//第2层的循环节假设g(g(g(n)))=g(g(y)),即mod3是y的循化节 16 17 __int64 array[2][2],sum[2][2]; 18 19 void MatrixMult(__int64 a[2][2],__int64 b[2][2],int mod){ 20 __int64 c[2][2]={0}; 21 for(int i=0;i<2;++i){ 22 for(int j=0;j<2;++j){ 23 for(int k=0;k<2;++k){ 24 c[i][j]+=a[i][k]*b[k][j]; 25 } 26 } 27 } 28 for(int i=0;i<2;++i){ 29 for(int j=0;j<2;++j)a[i][j]=c[i][j]%mod; 30 } 31 } 32 33 __int64 Matrix(__int64 k,int mod){ 34 array[0][0]=3,array[1][1]=0; 35 array[0][1]=array[1][0]=1; 36 sum[0][0]=sum[1][1]=1; 37 sum[0][1]=sum[1][0]=0; 38 while(k){ 39 if(k&1)MatrixMult(sum,array,mod); 40 MatrixMult(array,array,mod); 41 k>>=1; 42 } 43 return sum[0][0]; 44 } 45 46 int main(){ 47 /*__int64 a=0,b=1; 48 for(int i=2;;++i){//求循环节 49 a=(b*3+a)%mod2; 50 a=a^b; 51 b=a^b; 52 a=a^b; 53 if(a == 0 && b == 1){cout<<i-1<<endl;break;}//i-1=222222224 54 }*/ 55 __int64 n; 56 while(scanf("%I64d",&n)!=EOF){ 57 if(n>=2)n=Matrix(n-1,mod3); 58 if(n>=2)n=Matrix(n-1,mod2); 59 if(n>=2)n=Matrix(n-1,mod1); 60 printf("%I64d\n",n); 61 } 62 return 0; 63 }