标签:输入 水平 name 斐波那契 blank mod pre 循环 str
输入a, b, n, 计算f( a ^ b) % n , f( i ) = f( i - 1) + f( i - 2 ) , f( 0 ) = f(1) = 1, 其中,0 <= a , b <= 2 ^ 64, 0 <= n <= 1000
首先扔出两个结论(证明过程链接在此,个人水平有限看不懂。)
1.斐波那契数列模n 必有循环节。
2.斐波那契数列模n 的情况下,最多n^2项就会出现重复。
先找出循环节M,之后计算a^b%M 是多少,输出fib[a^b%M]即可
代码实现
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> typedef unsigned long long ll; using namespace std; const int maxn=1000+10; ll a,b; int f[maxn*maxn],n,M; int pow(ll a,ll p,int Mod) { int ret=1; while(p) { if(p & 1)ret*=a,ret%=Mod; a*=a;a%=Mod; p>>=1; } return ret; } inline void solve() { cin>>a>>b>>n; if(n==1||!a){printf("0\n");return ;} f[1]=1,f[2]=1; for(int i=3;i<=n*n+10;i++) { f[i]=f[i-1]+f[i-2];f[i]%=n; if(f[i]==f[2]&&f[i-1]==f[1]) {M=i-2;break;} } int k=pow(a%M,b,M); printf("%d\n",f[k]); } int main() { int T;cin>>T; while(T--) solve(); return 0; }
标签:输入 水平 name 斐波那契 blank mod pre 循环 str
原文地址:http://www.cnblogs.com/OIerLYF/p/7098328.html