码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-01-22 22:22:56      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:质数   测试   nbsp   opera   space   code   inf   return   amp   

知识概述

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

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

也就是求满足方程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 大步小步求离散模对数

标签:质数   测试   nbsp   opera   space   code   inf   return   amp   

原文地址:http://www.cnblogs.com/keshuqi/p/6341421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!