链接:点击打开链接
题意:求出F(a^b)^(F(a^b)^(n-1))%c(F为斐波那契数的值)
代码:
#include <iostream> #include <stdio.h> #include <algorithm> #include <math.h> using namespace std; unsigned long long f[20005]; //注意要使用无符号形 unsigned long long phi(unsigned long long n){ //欧拉函数值 unsigned long long sum=n,i; for(i=2;i*i<=n;i++){ if(n%i==0){ sum-=sum/i; while(n%i==0) n/=i; } } if(n>1) sum-=sum/n; return sum; } unsigned long long quickmod(unsigned long long a,unsigned long long b,unsigned long long m){ unsigned long long sum=1; //快速幂 a=a%m; while(b){ if(b&1) sum=sum*a%m; b>>=1; a=a*a%m; } return sum; } unsigned long long loop(unsigned long long m){ unsigned long long i; //求斐波那契数的循环节 f[0]=0;f[1]=1;f[2]=1; for(i=3;;i++){ f[i]=(f[i-1]+f[i-2])%m; if(f[i]==f[1]&&f[i-1]==f[0]) return i-1; } } int main(){ //这道题主要运用了两个性质: unsigned long long a,b,n,c,i,j,l,ph,cur,sum;//1.a^b≡(amodc)^bmod?(c)+?(c)(modc),b>=?(c) ?(c)为c的欧拉函数值 int k,t; //2.斐波那契数列有一个性质,它的n次方取模会出现一个循环节.假设循环节长度为len,则F(a^b)modc=F(a^bmodlen)modc cin>>t; for(k=1;k<=t;k++){ cin>>a>>b>>n>>c; printf("Case %d: ",k); if(c==1){ //c等于0时,模一定为0 printf("0\n"); continue; } //根据以上性质本题变为求F(a^b)^(F(a^b)^(n-1))%c(F()为斐波那契) ph=phi(c); //先求出欧拉函数值 l=loop(c); //求循环 cur=quickmod(a,b,l); cur=f[cur]; //求出F[a^b%len] if(ph==1){ //欧拉函数为1时单独考虑 cout<<quickmod(cur,n-1,c)<<endl; continue; } l=loop(ph); sum=quickmod(a,b,l); sum=f[sum]; //求出关于欧拉函数值F[a^b%len] sum=quickmod(sum,n-1,ph)+ph; cur=quickmod(cur,sum,c); //从而求出结果 cout<<cur<<endl; } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-10 21:29:19