zoukankan      html  css  js  c++  java
  • POJ 2417 Discrete Logging

    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 6190   Accepted: 2746

    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

     

    BSGS模板 

    屠龙宝刀点击就送

    #include <cstdio>
    #include <cmath>
    #include <map>
    using namespace std;
    map<long long,int>q;
    int P,B,N;
    long long ans;
    bool flag=false;
    long long ksm(int m,int n,int ha)
    {
        long long r=1,base=m;
        for(;n;n>>=1)
        {
            if(n&1)
                r=(r*base)%ha;
            base=(base*base)%ha;
        }
        return r;
    }
    void bsgs(long long y,long long z,long long p)
    {
        q.clear();
        int m=(int)ceil(sqrt((double)p));//防止编译错误
        flag=false;
        q[1]=m+1;
        long long a=1;
        for(int i=1;i<m;i++)
        {
            a=a*y%p;
            if(!q[a]) q[a]=i;
        }
        long long inv=1;
        a=ksm(y,p-m-1,p);
        for(int k=0;k<m;k++)
        {
            long long an=z*inv%p;
            if(q[an])
            {
                int v=q[an];
                if(v==m+1) {ans=k*m;flag=true;return;}
                else {ans=k*m+v;flag=true;return ;}
            }
            inv=inv*a%p;
        }
    }
    int main()
    {
        for(;scanf("%d%d%d",&P,&B,&N)!=EOF;)
        {
            if(B%P==0&&N==0) printf("1
    ");
            else if(B%P==0) printf("no solution
    ");
            else
            {
                bsgs(B,N,P);
                if(!flag) printf("no solution
    ");
                else printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    mysql备份及恢复
    mysql备份及恢复
    mysql备份及恢复
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7305029.html
Copyright © 2011-2022 走看看