zoukankan      html  css  js  c++  java
  • POJ-2417-Discrete Logging(BSGS)

    Given a prime P, 2 <= P < 2 31, 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) .

     

    题解

    这道题是裸的BSGS,具体内容可以看hzw的博客—传送门

     1 #include<algorithm>
     2 #include<map>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #define ll long long
     7 using namespace std;
     8 ll p,b,n,s,x,y,m,k;
     9 int exgcd(ll a,ll b){
    10     if (!b){
    11         x=1; y=0;
    12         return a;
    13     }
    14     int d=exgcd(b,a%b);
    15     ll t=x; x=y; y=t-(a/b)*y;
    16     return d;
    17 }
    18 map<int,int> h;
    19 int main(){
    20     while (~scanf("%lld%lld%lld",&p,&b,&n)){
    21         h.clear();
    22         ll t=(ll)sqrt(p);
    23         s=1; h[1]=t;
    24         for (int i=1;i<=t-1;i++){
    25             s=s*b%p;
    26             if (!h[s]) h[s]=i;
    27         }
    28         s=s*b%p;
    29         ll l=1e10,ans=n;
    30         exgcd(s,p);
    31         x=(x+p)%p;
    32         for (int i=0;i<=t;i++){
    33             if (h[ans]){
    34                 if (h[ans]==t) h[ans]=0;
    35                 l=i*t+h[ans];
    36                 break;
    37             }
    38             ans=ans*x%p;
    39         }
    40         if (l!=1e10) printf("%lld
    ",l);
    41                 else puts("no solution");
    42     }
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    连接数据库的几种方式
    c#拖拽文件
    设置webbrowser浏览器内核
    C#控件置于底层或顶层
    C#中读取xml文件指定节点
    关于selenium python Message: unknown error: Element is not clickable at point错误
    Linux的命令操作
    MySQL数据库的知识
    没有添加main方法
    eclipse导入已建工程
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7632822.html
Copyright © 2011-2022 走看看