• Discrete Logging


    Discrete Logging
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 5865   Accepted: 2618

    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模板题
     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<map>
     6 #define LL long long 
     7 using namespace std;
     8 LL a,b,c;
     9 map<LL,LL>mp;
    10 LL fastpow(LL a,LL p,LL c)
    11 {
    12     LL base=a;LL ans=1;
    13     while(p!=0)
    14     {
    15         if(p%2==1)ans=(ans*base)%c;
    16         base=(base*base)%c;
    17         p=p/2;
    18     }
    19     return ans;
    20 }
    21 int main()
    22 {
    23     // a^x = b (mod c)
    24     while(scanf("%lld%lld%lld",&c,&a,&b)!=EOF)
    25     {
    26         LL m=ceil(sqrt(c));// 注意要向上取整 
    27         mp.clear();
    28         if(a%c==0)
    29         {
    30         printf("no solution
    ");
    31         continue;
    32         }
    33         // 费马小定理的有解条件 
    34         LL ans;//储存每一次枚举的结果 b* a^j
    35         for(LL j=0;j<=m;j++)  // a^(i*m) = b * a^j
    36         {
    37             if(j==0)
    38             {
    39                 ans=b%c;
    40                 mp[ans]=j;// 处理 a^0 = 1 
    41                 continue;
    42             }
    43             ans=(ans*a)%c;// a^j 
    44             mp[ans]=j;// 储存每一次枚举的结果 
    45         }
    46         LL t=fastpow(a,m,c);
    47         ans=1;//a ^(i*m)
    48         LL flag=0;
    49         for(LL i=1;i<=m;i++)
    50         {
    51             ans=(ans*t)%c;
    52             if(mp[ans])
    53             {
    54                 LL out=i*m-mp[ans];// x= i*m-j
    55                 printf("%lld
    ",(out%c+c)%c);
    56                 flag=1;
    57                 break;
    58             }
    59             
    60         }
    61         if(!flag)
    62         printf("no solution
    ");    
    63     }
    64     
    65     return 0;
    66 }
  • 相关阅读:
    JAVA_WEB--jsp概述
    npr_news英语新闻听力——每日更新
    词根词缀高效背单词技巧--词霸天下完整版
    python刷LeetCode:1071. 字符串的最大公因子
    python刷LeetCode:1013. 将数组分成和相等的三个部分
    python刷LeetCode:543. 二叉树的直径
    python刷LeetCode:121. 买卖股票的最佳时机
    python刷LeetCode:38. 外观数列
    python刷LeetCode:35. 搜索插入位置
    python刷LeetCode:28. 实现 strStr()
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/6878968.html
Copyright © 2020-2023  润新知