我们定义一个f(n)函数,f(n) = a * f(n - 1) + b * f(n - 2), f(1) = c, f(2) = d.
问f(n)在模1000000007情况下的最小循环节。即求最小的m,使对任意的n有f(n) % 1000000007 = f(n + m) % 1000000007
这个题目不仅交不了,而且我还没办法验证代码的正确性,我还没办法
所以这里仅仅贴一份广义斐波纳契的代码,希望它是对的吧
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 typedef long long LL; 8 const int N = 2; 9 const LL MOD = 1000000007; 10 11 LL fac[2][505]; 12 int cnt,ct; 13 14 LL pri[6] = {2, 3, 7, 109, 167, 500000003}; 15 LL num[6] = {4, 2, 1, 2, 1, 1}; 16 17 struct Matrix 18 { 19 LL m[N][N]; 20 } ; 21 22 Matrix A; 23 Matrix I = {1, 0, 0, 1}; 24 25 Matrix multi(Matrix a,Matrix b) 26 { 27 Matrix c; 28 for(int i=0; i<N; i++) 29 { 30 for(int j=0; j<N; j++) 31 { 32 c.m[i][j] =0; 33 for(int k=0; k<N; k++) 34 { 35 c.m[i][j] += a.m[i][k] * b.m[k][j]; 36 c.m[i][j] %= MOD; 37 } 38 } 39 } 40 return c; 41 } 42 43 Matrix power(Matrix A,LL n) 44 { 45 Matrix ans = I, p = A; 46 while(n) 47 { 48 if(n & 1) 49 { 50 ans = multi(ans,p); 51 n--; 52 } 53 n >>= 1; 54 p = multi(p,p); 55 } 56 return ans; 57 } 58 59 LL quick_mod(LL a,LL b) 60 { 61 LL ans = 1; 62 a %= MOD; 63 while(b) 64 { 65 if(b & 1) 66 { 67 ans = ans * a % MOD; 68 b--; 69 } 70 b >>= 1; 71 a = a * a % MOD; 72 } 73 return ans; 74 } 75 76 LL Legendre(LL a,LL p) 77 { 78 LL t = quick_mod(a,(p-1)>>1); 79 if(t == 1) return 1; 80 return -1; 81 } 82 83 void dfs(int dept,LL product = 1) 84 { 85 if(dept == cnt) 86 { 87 fac[1][ct++] = product; 88 return; 89 } 90 for(int i=0; i<=num[dept]; i++) 91 { 92 dfs(dept+1,product); 93 product *= pri[dept]; 94 } 95 } 96 97 bool OK(Matrix A,LL n) 98 { 99 Matrix ans = power(A,n); 100 return ans.m[0][0] == 1 && ans.m[0][1] == 0 && 101 ans.m[1][0] == 0 && ans.m[1][1] == 1; 102 } 103 104 int main() 105 { 106 fac[0][0] = 1; 107 fac[0][1] = 2; 108 fac[0][2] = 500000003; 109 fac[0][3] = 1000000006; 110 LL a,b,c,d; 111 while(cin>>a>>b>>c>>d) 112 { 113 LL t = a * a + 4 * b; 114 A.m[0][0] = a; 115 A.m[0][1] = b; 116 A.m[1][0] = 1; 117 A.m[1][1] = 0; 118 if(Legendre(t,MOD) == 1) 119 { 120 for(int i=0; i<4; i++) 121 { 122 if(OK(A,fac[0][i])) 123 { 124 cout<<fac[0][i]<<endl; 125 break; 126 } 127 } 128 } 129 else 130 { 131 ct = 0; 132 cnt = 6; 133 dfs(0,1); 134 sort(fac[1],fac[1]+ct); 135 for(int i=0;i<ct;i++) 136 { 137 if(OK(A,fac[1][i])) 138 { 139 cout<<fac[1][i]<<endl; 140 break; 141 } 142 } 143 } 144 } 145 return 0; 146 }
当然,要附上博主的链接,做这个题的时候的玄学的数学方法,可能这辈子都不会再用到了
https://blog.csdn.net/ACdreamers/article/details/25616461
当然不能就这么算了,普通的斐波纳契数列求其模除一个数的循环节的题还是好找的
HDU3977
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int res; 6 int factor[33][2]; 7 long long len[1000005]; 8 struct Mat 9 { 10 long long mat[3][3]; 11 int row,col; 12 }; 13 long long gcd(long long a,long long b) 14 { 15 return b==0?a:gcd(b,a%b); 16 } 17 long long lcm(long long a,long long b) 18 { 19 return a/gcd(a,b)*b; 20 } 21 Mat mod_mul(Mat a,Mat b,long long p) 22 { 23 Mat ans; 24 ans.row=a.row; 25 ans.col=b.col; 26 memset(ans.mat,0,sizeof(ans.mat)); 27 for(int i=0;i<ans.row;i++) 28 for(int k=0;k<a.col;k++) 29 if(a.mat[i][k]) 30 for(int j=0;j<ans.col;j++) 31 { 32 ans.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; 33 ans.mat[i][j]%=p; 34 } 35 return ans; 36 } 37 Mat mod_pow(Mat a,long long k,long long p) 38 { 39 Mat ans; 40 ans.row=a.row; 41 ans.col=a.col; 42 for(int i=0;i<a.row;i++) 43 for(int j=0;j<a.col;j++) 44 ans.mat[i][j]=(i==j); 45 while(k) 46 { 47 if(k&1) ans=mod_mul(ans,a,p); 48 a=mod_mul(a,a,p); 49 k>>=1; 50 } 51 return ans; 52 } 53 long long deal(int x) 54 { 55 if(len[x]!=-1) return len[x]; 56 Mat A; 57 A.mat[0][0]=A.mat[0][1]=A.mat[1][0]=1,A.mat[1][1]=0; 58 A.row=A.col=2; 59 long long p=1ll*(x-1)*(x+1); 60 long long ans=p; 61 for(long long i=2;i*i<p;i++) 62 if(p%i==0) 63 { 64 Mat B=mod_pow(A,i,x); 65 if(B.mat[0][0]==1&&B.mat[0][1]==0) 66 if(B.mat[1][0]==0&&B.mat[1][1]==1) 67 ans=min(ans,i); 68 B=mod_pow(A,p/i,x); 69 if(B.mat[0][0]==1&&B.mat[0][1]==0) 70 if(B.mat[1][0]==0&&B.mat[1][1]==1) 71 ans=min(ans,p/i); 72 } 73 return len[x]=ans; 74 } 75 void get_factor(int p) 76 { 77 res=0; 78 for(int i=2;i*i<=p;i++) 79 if(p%i==0) 80 { 81 factor[res][0]=i,factor[res][1]=0; 82 while(p%i==0) p/=i,factor[res][1]++; 83 res++; 84 } 85 if(p>1) factor[res][0]=p,factor[res++][1]=1; 86 } 87 int main() 88 { 89 memset(len,-1,sizeof(len)); 90 len[1]=1,len[2]=3,len[3]=8,len[4]=6,len[5]=20; 91 int T,p,cas=1; 92 scanf("%d",&T); 93 while(T--) 94 { 95 scanf("%d",&p); 96 get_factor(p); 97 long long ans=1; 98 for(int i=0;i<res;i++) 99 { 100 long long tmp=deal(factor[i][0]); 101 for(int j=1;j<factor[i][1];j++) tmp*=factor[i][0]; 102 ans=lcm(ans,tmp); 103 } 104 printf("Case #%d: %lld ",cas++,ans); 105 } 106 }
这个坑等数学学好了再滚回来填(可能数学学不好了QAQ)