问题 G: 【一本通提高同余问题】计算器
模板题,最重要的是BSGS算法
#include<bits/stdc++.h> using namespace std; long long T,K,opt; long long yy,z,p,ans1,ans2,ans3; long long newans; long long x,y; long long Quickpow(long long x,long long n,long long mod) { long long base=1; while(n) { if(n&1) { base=(long long)base*x%mod; } n>>=1; x=x*x%mod; } return base; } long long Exgcd(long long a,long long &x,long long b,long long &y) { if(b==0) { x=1; y=0; return a; } long long Gcd=Exgcd(b,x,a%b,y); long long tmp; tmp=x; x=y; y=tmp-(a/b)*y; return Gcd; } long long BSGS(long long a,long long b,long long p) { map<long,long>hash; hash.clear(); b%=p; int t=(int)sqrt(p)+1; for(int j=0;j<t;j++) { int val=(long long)b*Quickpow(a,j,p)%p; hash[val]=j; } a=Quickpow(a,t,p); if(a==0) { if(b==0) { return 1; } else { return -1; } } for(int i=0;i<=t;i++) { int val=(int)Quickpow(a,i,p); int j=hash.find(val)==hash.end()?-1:hash[val]; if(j>=0&&i*t-j>=0) { return i*t-j; } } return -1; } int main() { scanf("%lld%lld",&T,&K); while(T--) { if(K==1) { cin>>yy>>z>>p; ans1=Quickpow(yy,z,p); cout<<ans1<<endl; } else if(K==2) { cin>>yy>>z>>p; ans2=Exgcd(yy,x,p,y); if(z%ans2!=0) { printf("Orz, I cannot find x!\n"); continue; } else { newans=((x*(z/ans2))%(p/ans2)+(p/ans2))%(p/ans2); } cout<<newans<<endl; } else if(K==3) { cin>>yy>>z>>p; ans3=BSGS(yy,z,p); if(ans3==-1) { printf("Orz, I cannot find x!\n"); continue; } else { cout<<ans3<<endl; } } } return 0; }