数学:广义斐波纳契数列循环节

我们定义一个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\n",cas++,ans);
105     }
106 }

这个坑等数学学好了再滚回来填(可能数学学不好了QAQ)

posted @ 2018-09-01 10:53  静听风吟。  阅读(504)  评论(0编辑  收藏  举报