【POJ3243】Clever Y-扩展BSGS算法
测试地址:Clever Y
题目大意:求关于的方程的最小非负整数解。
做法:本题需要用到扩展BSGS算法。
这个东西我觉得这篇文章讲得很清楚了,我自己来说可能讲得不比原来的题解清楚,所以这里就直接贴出链接:点我。
以下是本人代码:
#include <bits/stdc++.h>
#define ll long long
#define hashsiz 1000007
using namespace std;
ll A,B,C,mp[hashsiz+10],hash[hashsiz+10];
ll gcd(ll a,ll b)
{
return (b==0)?a:gcd(b,a%b);
}
ll power(ll a,ll b)
{
ll s=1,ss=a;
while(b)
{
if (b&1) s=(s*ss)%C;
ss=(ss*ss)%C,b>>=1;
}
return s;
}
ll hashfind(ll x)
{
ll s=x%hashsiz;
while (hash[s]!=-1&&hash[s]!=x) s++;
return s;
}
ll hashinsert(ll x)
{
ll s;
hash[s=hashfind(x)]=x;
return s;
}
int main()
{
while(scanf("%lld%lld%lld",&A,&C,&B)&&(A||B||C))
{
memset(mp,0,sizeof(mp));
memset(hash,-1,sizeof(hash));
ll m=ceil(sqrt((double)C));
ll D=1,d=gcd(A,C),num=0;
bool flag=1;
while(d!=1)
{
if (B%d!=0) {flag=0;break;}
B/=d,C/=d;
D=(D*A/d)%C;
d=gcd(A,C);
num++;
}
if (!flag)
{
if (B==1) printf("%d\n",num);
else printf("No Solution\n");
continue;
}
flag=0;
ll x=1,n=A;
for(ll i=0;i<num;i++,x=(x*n)%C)
if (x==B) {printf("%lld\n",i);flag=1;break;}
if (flag) continue;
x=1,n=A;
for(ll i=0;i<=m;i++,x=(x*n)%C)
{
ll pos=hashinsert((x*B)%C);
mp[pos]=i+1;
}
x=D,n=power(A,m);
x=(x*n)%C;
flag=0;
for(ll i=1;i<=m;i++,x=(x*n)%C)
{
int pos=hashfind(x);
if (mp[pos])
{
printf("%lld\n",i*m-mp[pos]+1+num);
flag=1;
break;
}
}
if (!flag) printf("No Solution\n");
}
return 0;
}