恶补数论 Baby-Step-Giant-Step 大步小步求离散模对数

Posted AronQi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了恶补数论 Baby-Step-Giant-Step 大步小步求离散模对数相关的知识,希望对你有一定的参考价值。

知识概述

好吧,我承认这是我初三寒假就听过的知识,然而我现在早就高一了(又是寒假,只不过我已经在省选了...)

额,这是求离散模对数的一种算法

也就是求满足方程a^x≡b(mod p)的最小的x(其中p为质数)

考虑将x分块?,根据欧拉定理,只需检查x=0,1,2...p-1是否是解即可,因为a^(p-1)≡1(mod p)当x超过p-1时就开始循环了哦

假设块的大小为m

先检查前m项,a^0,a^1,a^2...a^(m-1)是否满足要求,把ai mod p存在hash表ei里,求出a^m的逆a^(-m)

再考虑下面的m项,a^m,a^(m+1),a^(m+2),...,a^(2m-1),若存在解,则相当于存在i使ei*a^m≡b(mod n),两边左乘a^(-m)得ei≡b ‘ (mod n) (b ‘ =a^(-m)*b(mod p)).这样,只需检查是否存在ei=b ‘ 即可

模板

做个hash表吧

未测试模板1.0

//orz PoPoQQQ
#include <math.h>
#define dmin(a,b) ((a)<(b)?(a):(b))

int p;//p is a prime.

struct Pep{
    int first,second;

    Pep(int _=0,int __=0) : first(_),second(__) {}

    bool operator < (const Pep &other) const {
        return first < other.first;
    }
}

namespace Hash_Table{
#define inf ~0U>>1
#define MaxN 10010
    struct Linker{
        int hash,val;
        Linker *next;
        Linker(int _,Linker *__) : hash(_),val(inf),next(__) {}
    }*fir[MaxN];

    inline int &Hash(int x){
        int pos=x%MaxN;
        for(Linker *iter=fir[pos];iter;iter=iter->next)
            if(iter->hash==x)
                return iter->val;
        return (fir[pos]=new Linker(x,fir[pos]))->val;
    }
}

inline Pep exgcd(int a,int b){
    if(!b)return Pep(1,0);
    Pep temp=exgcd(b,a%b);
    return Pep(temp.second,temp.first-x/y*temp.second);
}

inline int Baby_Step_Giant_Step(int A,int B){
    int i,m=ceil(sqrt(p)),temp=1,D=1;
    for(i=0;i<=m;i++,(temp*=A)%=p){
        int &val=Hash_Table::Hash(temp);
        val=dmin(val,i);
        D=temp;
    }
    for(temp=1,i=0;i<=m;i++,(temp*=D)%=p){
        int x=((exgcd(temp,p).first%p)+p)%p;
        int &val=Hash_Table::Hash(x*B%p);
        if(val!=inf)return i*m+val;
    }
    return -1;
}

 

以上是关于恶补数论 Baby-Step-Giant-Step 大步小步求离散模对数的主要内容,如果未能解决你的问题,请参考以下文章

BSGS(Baby-Step-Giant-Step)算法及其应用

Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)

Net基础恶补

跳槽时你需要恶补数据结构和算法吗?

linux&oraclelinux&oracle恶补篇

恶补---bell数