# bzoj3122: [Sdoi2013]随机数生成器（BSGS）

http://www.lydsy.com/JudgeOnline/problem.php?id=3122

#include<map>
#include<cmath>
#include<cstdio>
#include<iostream>

using namespace std;

int p,a,b,x1,t;

map<int,int>mp;

{
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;
while(T--)
{
if(x1==t)
{
printf("1\n");
continue;
}
if(p<=100) force();
else if(a==1) A1();
else if(!b) BSGS();
else bsgs();
}
}

posted @ 2018-03-06 16:03  TRTTG  阅读(243)  评论(0编辑  收藏  举报