题目大意:……简洁明了自己看
第一问快速幂
第二问扩展欧几里得
第三问BSGS
顺便一开始没看到p是质数0.0 去弄了EXBSGS的模板0.0 懒得改了
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1001001 using namespace std; typedef long long ll; typedef pair<ll,ll> abcd; ll A,B,C,D,hash_table[M],val[M],tim[M],tot; int Hash(ll x) { int pos=x%M; while(1) { if(tim[pos]!=tot) tim[pos]=tot,hash_table[pos]=-1,val[pos]=0x3f3f3f3f; if(hash_table[pos]==-1||hash_table[pos]==x) return hash_table[pos]=x,pos; else ++pos,pos%=M; } } int Get_Hash(ll x) { int pos=x%M; while(1) { if(tim[pos]!=tot) tim[pos]=tot,hash_table[pos]=-1; if(hash_table[pos]==-1) return -1; if(hash_table[pos]==x) return pos; else ++pos,pos%=M; } } ll GCD(ll x,ll y) { return y?GCD(y,x%y):x; } abcd EXGCD(ll x,ll y) { if(!y) return abcd(1,0); abcd temp=EXGCD(y,x%y); return abcd(temp.second,temp.first-x/y*temp.second); } ll Inverse(ll x) { ll temp=EXGCD(x,C).first; return (temp%C+C)%C; } ll EXBSGS() { ll i,m,cnt=0,temp,base=1; int pos; B%=C; for(i=0,temp=1%C;i<=50;i++,temp*=A,temp%=C) if(temp==B) return i; D=1; while(temp=GCD(A,C),temp!=1) { if(B%temp) return -1; ++cnt; B/=temp; C/=temp; D*=A/temp; D%=C; } B*=Inverse(D);B%=C; m=(ll)ceil(sqrt(C)+1e-5); ++tot; for(i=0,temp=1%C;i<m;i++,temp*=A,temp%=C) pos=Hash(temp),val[pos]=min(val[pos],i); for(i=1,base=1%C;i<=m;i++,base*=A,base%=C); for(i=0,D=1%C;i<m;i++,D*=base,D%=C) { temp=EXGCD(D,C).first*B; temp=(temp%C+C)%C; pos=Get_Hash(temp); if(~pos) return i*m+val[pos]+cnt; } return -1; } ll KSM() { ll re=1; while(B) { if(B&1)re*=A,re%=C; A*=A,A%=C; B>>=1; } return re; } ll EXGCD() { if(A%C==0&&B%C!=0) return -1; return (EXGCD(A,C).first%C*B%C+C)%C; } int main() { int T,k; ll ans; for(cin>>T>>k;T;T--) { cin>>A>>B>>C; switch(k) { case 1:ans=KSM();break; case 2:ans=EXGCD();break; case 3:ans=EXBSGS();break; } if(ans==-1) puts("Orz, I cannot find x!"); else cout<<ans<<endl; } }
时间: 2024-10-12 22:30:35