bzoj5296 [Cqoi2018]破解D-H协议【BSGS】

先把a求出来,然后求B^a,即可;

已知A  ≡ g^a (mod P) ,求 a,

设a=i*m-j  ===> A*(g^j) ≡ g^i(*m)     (mod P);

枚举 i,j ==>  i的范围 为0---> ceil(sqrt(P)); j的 范围 1----->ceii(sqrt(P));

 先枚举j 将 A*(g^j)存到map里 mp[A*(g^j)]=j;

然后枚举i 寻找mp[g^(i*m)]不为0的第一个值,就是i的答案 ==》a=i*m-mp[g^(i*m)];

至于 i,j,的取值范围 详见:复制+粘贴

bzoj5296 [Cqoi2018]破解D-H协议【BSGS】_第1张图片

AC代码

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
mapmp;
LL quc(LL a,LL b,LL mod)
{
    LL res=1;
    while (b)
    {
        if (b&1)
            res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
int main()
{
    LL g,mod,a,b;
    scanf("%lld%lld",&g,&mod);
    int n;
    LL v=ceil(sqrt(mod));
    scanf("%d",&n);
    while (n--)
    {
        scanf("%lld%lld",&a,&b);
        mp.clear();
        LL vv=a;
        for (int j=0;j<=v;j++)
        {
            if (!j)
            {
                vv=a%mod;
                mp[vv]=j;continue;
            }
            vv=vv*g%mod;
            mp[vv]=j;
        }
        LL pp=quc(g,v,mod),ss=1;
        LL re;
        for (int i=1;i<=v;i++)
        {
            ss=ss*pp%mod;
            if (mp[ss])
            {
                re=i*v-mp[ss];
                re=(re%mod+mod)%mod;
                break;
            }
        }
        printf("%lld\n",quc(b,re,mod));
    }
    return 0;
}

 

 

你可能感兴趣的:(BSGS模板,bzoj)