# bzoj2242: [SDOI2011]计算器（BSGS）

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

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

using namespace std;

int y,z,p;

map<int,int>mp;

int Pow(int a,int b,int m)
{
int ans=1;
for(;b;a=1LL*a*a%m,b>>=1)
if(b&1) ans=1LL*ans*a%m;
return ans;
}

int gcd(int a,int b) { return !b ? a : gcd(b,a%b); }

void exgcd(int a,int b,long long &x,long long &y)
{
if(!b) { x=1; y=0; return; }
exgcd(b,a%b,y,x); y-=a/b*x;
}

void bsgs()
{
mp.clear();
int m=ceil(sqrt(p));
int mul=z;
//mp[z]=0;
for(int j=1;j<=m;++j)
{
mul=1LL*y*mul%p;
mp[mul]=j;
}
int am=Pow(y,m,p);
mul=1;
for(int j=1;j<=m;++j)
{
mul=1LL*mul*am%p;
if(mp.find(mul)!=mp.end())
{
printf("%d\n",j*m-mp[mul]);
return;
}
}
puts("Orz, I cannot find x!");
}

int main()
{
int T,k;
scanf("%d%d",&T,&k);
if(k==1)
while(T--)
{
scanf("%d%d%d",&y,&z,&p);
printf("%d\n",Pow(y,z,p));
}
else if(k==2)
{
long long x0,y0;
int g;
while(T--)
{
scanf("%d%d%d",&y,&z,&p);
g=gcd(y,p);
if(z%g) puts("Orz, I cannot find x!");
else
{
y/=g; p/=g;
exgcd(y,p,x0,y0);
x0=(x0%p+p)%p;
x0=x0*z/g%p;
printf("%lld\n",x0);
}
}
}
else
while(T--)
{
scanf("%d%d%d",&y,&z,&p);
if(!(y%p)) puts("Orz, I cannot find x!");
else bsgs();
}
return 0;
}

posted @ 2018-02-24 00:35  TRTTG  阅读(163)  评论(0编辑  收藏  举报