zoukankan      html  css  js  c++  java
  • POJ2417 Discrete Logging【BSGS】

    Discrete Logging
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 5577   Accepted: 2494

    Description

    Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that 
        B
    L
     == N (mod P)

    Input

    Read several lines of input, each containing P,B,N separated by a space.

    Output

    For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print "no solution".

    Sample Input

    5 2 1
    5 2 2
    5 2 3
    5 2 4
    5 3 1
    5 3 2
    5 3 3
    5 3 4
    5 4 1
    5 4 2
    5 4 3
    5 4 4
    12345701 2 1111111
    1111111121 65537 1111111111
    

    Sample Output

    0
    1
    3
    2
    0
    3
    1
    2
    0
    no solution
    no solution
    1
    9584351
    462803587
    

    Hint

    The solution to this problem requires a well known result in number theory that is probably expected of you for Putnam but not ACM competitions. It is Fermat's theorem that states 
       B
    (P-1)
     == 1 (mod P)

    for any prime P and some other (fairly rare) numbers known as base-B pseudoprimes. A rarer subset of the base-B pseudoprimes, known as Carmichael numbers, are pseudoprimes for every base between 2 and P-1. A corollary to Fermat's theorem is that for any m 
       B
    (-m)
     == B
    (P-1-m)
     (mod P) .

    Source

     
    高次同余方程。   BL == N (mod P)求解最小的L
    BSGS模板题目。
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    struct Thash{
        static const int MOD=233333;
        static const int MAXN=1e6+5;
        int tot,head[MOD+100],next[MAXN],h[MAXN],val[MAXN];
        inline void clear(){tot=0;memset(head,0,sizeof head);}
        inline void insert(int H,int VAL){
            for(int i=head[H%MOD];i;i=next[i]) if(h[i]==H){val[i]=VAL;return ;}
            h[++tot]=H;val[tot]=VAL;next[tot]=head[H%MOD];head[H%MOD]=tot;
        }
        inline int get(int H){
            for(int i=head[H%MOD];i;i=next[i]) if(h[i]==H) return val[i];
            return 0;
        }
    }M;
    inline ll fpow(ll a,ll p,ll mod){
        int res=1;
        for(;p;p>>=1,a=a*a%mod) if(p&1) res=res*a%mod;
        return res;
    }
    int BSGS(ll A,ll B,ll mod){
        A%=mod;
        if(!A){
            if(!B) return 1;
            return -1;
        }
        ll m=sqrt(mod)+1,ni=fpow(A,mod-m-1,mod);
        ll t=1,y=1;
        M.clear();
        M.insert(1,m+1); 
        for(int i=1;i<m;i++){
            t=t*A%mod;
            if(!M.get(t)) M.insert(t,i); 
        }
        for(int i=0;i<m;i++){
            int u=M.get(B*y%mod);
            if(u){
                if(u==m+1) u=0;
                return i*m+u;
            }
            y=y*ni%mod;
        }
        return -1;
    }
    int main(){
        int a,b,c,ans(-1);
        while(scanf("%d%d%d",&c,&a,&b)==3){
            ans=BSGS(a,b,c);
            if(~ans) printf("%d
    ",ans);
            else puts("no solution");
        }
        return 0;
    }
  • 相关阅读:
    小作业5
    小作业4
    Matplotlib基础
    Numpy学习笔记(下篇)
    Numpy学习笔记(上篇)
    机器学习的经典算法与应用
    opencv学习笔记D01
    Markdown新手入门
    python之生成器yeild
    pyinstaller打包.py程序为.exe操作指南
  • 原文地址:https://www.cnblogs.com/shenben/p/6516478.html
Copyright © 2011-2022 走看看