hdu 2815 Mod Tree (exBSGS)

http://acm.hdu.edu.cn/showproblem.php?pid=2815

//解 K^D ≡ N mod P
#include<map>
#include<cmath>
#include<cstdio>
#include<iostream>

using namespace std; 

map<int,int>mp;

typedef long long LL;

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}    

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

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

LL exBSGS(int A,int B,int C)
{
    if(B==1) return 0;
    int k=0,tmp=1,d;
    while(1)
    {
        d=gcd(A,C);
        if(d==1) break;
        if(B%d) return -1;
        B/=d; C/=d;
        tmp=1LL*tmp*(A/d)%C;
        k++;
        if(tmp==B) return k;
    }
    mp.clear();
    int m=ceil(sqrt(1.0*C));
    mp[B]=0;
    int mul=B;
    for(int j=1;j<=m;++j)
    {
        mul=1LL*mul*A%C;
        mp[mul]=j;
    }
    int am=Pow(A,m,C);
    mul=tmp;
    for(int j=1;j<=m;++j)
    {
        mul=1LL*mul*am%C;
        if(mp.find(mul)!=mp.end()) return 1LL*j*m-mp[mul]+k;
    }
    return -1;
}

int main()
{
    int k,p,n;
    LL d;
    while(scanf("%d",&k)!=EOF)
    {
        read(p); read(n);
        if(n>=p) 
        {
            puts("Orz,I can’t find D!");
            continue;
        }
        d=exBSGS(k,n,p);
        if(d==-1) puts("Orz,I can’t find D!");
        else cout<<d<<'
'; 
    }
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8973001.html