题解 P4195 【【模板】exBSGS/Spoj3105 Mod】

· · 题解

之前题解被叉了,upt了一下,应该没问题了吧...?

Code:

#include <cstdio>
#include <cctype>
#include <cmath>
#include <unordered_map>
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
template <class T>
inline void read(T &x)
{
    x=0;char c=gc();
    while(!isdigit(c)) c=gc();
    while(isdigit(c)) x=x*10+c-'0',c=gc();
}
std::unordered_map <int,int> Hash;
#define mul(a,b,p) (1ll*(a)*(b)%p)
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int exBSGS(int a,int b,int p)
{
    a%=p,b%=p;
    if(b==1) return 0;
    if(!b&&!a) return 1;
    if(!a) return -1;
    if(!b)
    {
        int ret=0,d;
        while((d=gcd(a,p))!=1)
        {
            ++ret,p/=d;
            if(p==1) return ret;
        }
        return -1;
    }
    int ret=0,A=a,B=b,P=p,C=1,d;
    while((d=gcd(A,P))!=1)
    {
        if(B%d) return -1;
        P/=d,B/=d;
        C=mul(C,A/d,P);
        ++ret;
        if(C==B) return ret;
    }
    Hash.clear();
    int f=1,t=sqrt(P)+1;
    for(int i=0;i<t;i++)
    {
        Hash[mul(f,B,P)]=i;
        f=mul(f,A,P);
    }
    int tf=f;
    f=mul(f,C,P);
    for(int i=1;i<=t;i++)
    {
        if(Hash.find(f)!=Hash.end()) return ret+i*t-Hash[f];
        f=mul(f,tf,P);
    }
    return -1;
}
int main()
{
    int a,p,b;read(a),read(p),read(b);
    while(a&&p&&b)
    {
        int ans=exBSGS(a,b,p);
        if(~ans) printf("%d\n",ans);
        else puts("No Solution");
        read(a),read(p),read(b);
    }
    return 0;
}