hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***

时间:2023-03-08 21:31:46
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的循环节

所以最终结果只要进行矩阵快速幂即可求出

循环节

 #include<stdio.h>

 const long long MOD=;//第一次是MOD=1000000007 找出循环节是222222224
//第二次是MOD=222222224,找出循环节183120
int main()
{
long long a,b;
a=;
b=;
for(int i=;;i++)
{
if(a==&&b==)
{
printf("%d\n",i);
break;
}
long long c=*b+a;
c%=MOD;
a=b;
b=c;
}
return ;
}
 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std; const int mod1=;//求结果的循环节
const int mod2=;//第1层的循环节,假设g(g(g(n)))=g(x),即mod2是x的循环节
const int mod3=;//第2层的循环节假设g(g(g(n)))=g(g(y)),即mod3是y的循化节 __int64 array[][],sum[][]; void MatrixMult(__int64 a[][],__int64 b[][],int mod){
__int64 c[][]={};
for(int i=;i<;++i){
for(int j=;j<;++j){
for(int k=;k<;++k){
c[i][j]+=a[i][k]*b[k][j];
}
}
}
for(int i=;i<;++i){
for(int j=;j<;++j)a[i][j]=c[i][j]%mod;
}
} __int64 Matrix(__int64 k,int mod){
array[][]=,array[][]=;
array[][]=array[][]=;
sum[][]=sum[][]=;
sum[][]=sum[][]=;
while(k){
if(k&)MatrixMult(sum,array,mod);
MatrixMult(array,array,mod);
k>>=;
}
return sum[][];
} int main(){
/*__int64 a=0,b=1;
for(int i=2;;++i){//求循环节
a=(b*3+a)%mod2;
a=a^b;
b=a^b;
a=a^b;
if(a == 0 && b == 1){cout<<i-1<<endl;break;}//i-1=222222224
}*/
__int64 n;
while(scanf("%I64d",&n)!=EOF){
if(n>=)n=Matrix(n-,mod3);
if(n>=)n=Matrix(n-,mod2);
if(n>=)n=Matrix(n-,mod1);
printf("%I64d\n",n);
}
return ;
}