hdu 2815 Mod Tree (exBSGS)

Posted 日拱一卒 功不唐捐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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<<\n; 
    }
}

 

以上是关于hdu 2815 Mod Tree (exBSGS)的主要内容,如果未能解决你的问题,请参考以下文章

HDU2815 Mod Tree大步小步法

hdu2815-Mod Tree高次同余方程-拓展BadyStepGaintStep

离散对数二连 poj 2417 Discrete Logging & HDU 2815 Mod Tree

BSGS与ExBSGS:大步小步法

省选算法学习-BSGS与exBSGS

BZOJ1467/2480Pku3243 clever Y/Spoj3105 Mod EXBSGS