题意:两个非负整数a,b<2^64 计算斐波拉契序列f(a^b)mod x (x<1000)
思路:显然a^b只能用快速幂,而且还必须要取模,所以去尝试找f(n)mod x的周期
不能发现当二元组(f[i]%x,fp[i-1]%x)=(f[0]%x,f[1]%x) 的时候开始循环,所以周期为i
因为f[n]%x的余数最多只有1000种所以在f[0...n^2]以内就能找到周期
<span style="font-size:14px;">// Accepted C++ 0.096 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; typedef unsigned long long ll; int period[1005]; int an[101000]; ll powmod(ll a,ll b,ll mod) { ll ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } int main() { int T; scanf("%d",&T); int a0,a1; for(int i=1;i<=1000;i++) { a0=0%i,a1=1%i; for(int j=2;;j++) { int a2=(a0+a1)%i; if(a2==1%i&&a1==0) {period[i]=j-1;break;} //存周期 a0=a1,a1=a2; } } while(T--) { ll a,b; int mod; cin>>a>>b>>mod; int p=powmod(a%period[mod],b,period[mod]); an[0]=0,an[1]=1%mod; for(int i=2;i<=p;i++) an[i]=(an[i-1]+an[i-2])%mod; if(a==0&&b==0) puts("0"); else printf("%d\n",an[p]); } return 0; } </span>
时间: 2024-11-05 18:51:41