bzoj3122: [Sdoi2013]随机数生成器(BSGS)
http://www.lydsy.com/JudgeOnline/problem.php?id=3122
等比数列求和公式+BSGS
#include<map> #include<cmath> #include<cstdio> #include<iostream> using namespace std; int p,a,b,x1,t; map<int,int>mp; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } int Pow(int x,int y) { int r=1; for(;y;x=1LL*x*x%p,y>>=1) if(y&1) r=1LL*r*x%p; return r; } void force() { int ans=-1; int last=x1,now; for(int i=2;i<=p;++i) { now=(1LL*a*last+b)%p; if(now==t) { ans=i; break; } last=now; } printf("%d\n",ans); } void A1() { if(!b) printf("-1\n"); else printf("%d\n",int((1LL*(t-x1+p)%p*Pow(b,p-2)%p+1)%p)); } void BSGS() { if(!a) { if(t==x1) printf("1\n"); else if(t==b) printf("2\n"); else printf("-1\n"); return; } int ans=-1; mp.clear(); int B=1LL*t*Pow(x1,p-2)%p; int m=ceil(1.0*sqrt(1.0*p)); int mul=B; mp[B]=0; for(int i=1;i<m;++i) { mul=1LL*mul*a%p; mp[mul]=i; } mul=1; int am=Pow(a,m); for(int i=1;i<=m;++i) { mul=1LL*mul*am%p; if(mp.find(mul)!=mp.end()) { ans=i*m-mp[mul]; break; } } if(ans!=-1) ans++; printf("%d\n",ans); } void bsgs() { if(!a) { if(t==x1) printf("1\n"); else if(t==b) printf("2\n"); else printf("-1\n"); return; } int ans=-1; mp.clear(); int tmp=1LL*b*Pow(a-1,p-2)%p; int B=1LL*(t+tmp)*Pow(x1+tmp,p-2)%p; int m=ceil(1.0*sqrt(1.0*p)); int mul=B; mp[B]=0; for(int i=1;i<m;++i) { mul=1LL*mul*a%p; mp[mul]=i; } mul=1; int am=Pow(a,m); for(int i=1;i<=m;++i) { mul=1LL*mul*am%p; if(mp.find(mul)!=mp.end()) { ans=i*m-mp[mul]; break; } } if(ans!=-1) ans++; printf("%d\n",ans); } int main() { //freopen("random.in","r",stdin); //freopen("random.out","w",stdout); int T; read(T); while(T--) { read(p); read(a); read(b); read(x1); read(t); if(x1==t) { printf("1\n"); continue; } if(p<=100) force(); else if(a==1) A1(); else if(!b) BSGS(); else bsgs(); } }