AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2480
【吐槽】
一道很简单的模板题。
当p=1时记得要特判。。。(博主因为这个wa了无数次)
/*************
bzoj 2480
by chty
2016.11.8
*************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
#define mod 99991
typedef long long ll;
struct node{ll v,num,f;}hash[mod+10];
ll A,B,C;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
ll gcd(ll a,ll b) {return !b?a:gcd(b,a%b);}
void insert(ll v,ll x)
{
ll t=v%mod;
while(hash[t].f&&hash[t].v!=v) {t++; if(t>mod) t-=mod;}
if(!hash[t].f) {hash[t].f=1;hash[t].num=x;hash[t].v=v;}
}
ll find(ll v)
{
ll t=v%mod;
while(hash[t].f&&hash[t].v!=v) {t++; if(t>mod) t-=mod;}
if(!hash[t].f) return -1;
else return hash[t].num;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) {x=1; y=0; return;}
exgcd(b,a%b,x,y);
ll t=x;x=y;y=t-a/b*y;
}
ll Shank()
{
ll ret=1;
for(ll i=0;i<=50;i++) {if(ret==B) return i;ret=ret*A%C;}
ll temp,ans(1),cnt(0);
while((temp=gcd(A,C))!=1)
{
if(B%temp) return -1;
C/=temp; B/=temp;
ans=ans*(A/temp)%C;
cnt++;
}
ll m=(ll)ceil(sqrt(C*1.0)),t(1);
for(ll i=0;i<m;i++) {insert(t,i);t=t*A%C;}
for(ll i=0;i<m;i++)
{
ll x,y;
exgcd(ans,C,x,y);
ll val=x*B%C;
val=(val%C+C)%C;
ll j=find(val);
if(j!=-1) return m*i+j+cnt;
ans=ans*t%C;
}
return -1;
}
void pre() {for(int i=0;i<=mod;i++)hash[i].f=0,hash[i].num=hash[i].v=-1;}
int main()
{
freopen("cin.in","r",stdin);
freopen("cout.out","w",stdout);
while(~scanf("%d%d%d",&A,&C,&B))
{
if(!(A+B+C)) break;
if(C==1) {puts("0"); continue;}
pre(); A%=C; B%=C;
ll ans=Shank();
if(ans==-1) puts("No Solution");
else printf("%lld\n",ans);
}
return 0;
}