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

    题目描述

    Given a prime P,2<=P<231P, 2 <= P < 2^{31}P,2<=P<231​​, an integer B,2<=B<PB, 2 <= B < PB,2<=B<P, and an integer N,1<=N<PN, 1 <= N < PN,1<=N<P, compute the discrete logarithm of NNN, base BBB, modulo PPP. That is, find an integer LLL such that

    BL==N(modP)B^L == N (mod P)BL​​==N(modP)

    输入格式

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

    输出格式

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

    样例

    样例输入

    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

    样例输出

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

    数据范围与提示

    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(modP)

    for any prime PPP 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)(modP)

    背景

      这题的英文题面是真的没有翻译!!!!

      差评。

      看懂题面简直费死劲了。

      结果还是导致了理解偏差QAQ,发此博客献给我的英语老师 Mr.jia


    思路分析

      ? 你们知道北上广深嘛?

      指 BSGS算法 ,我今日的研究成果。

      其实如果知道这个算法,那么这道题就只是个代码实现了。【确认过,是板子

      那么我来具体介绍一下这个算法。

      BSGS

        明确:BSGS用于求解高次同余方程的整数解。

              

        上面就是一个高次同余方程。

        我们来思考一下,有没有什么定理啊,推论啊能够化简这个式子。

      ·   在求解这个问题之前,我们先假设A与C互质。【A和C不互质的情况,先进行消因子处理成互质的。

        然后,根据费马小定理可以得到 :

          当A和C互质的时候,有如下:

            

          所以循环节的长度不会大于c,即数据小的时候,可以枚举 0≤x≤c-1

        那么,数据大了怎么办呢?

        这就要用到BSGS了。

          

        具体就是代码实现了。


    代码实现

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #define ll long long 
    #define rint register int 
    using namespace std;
    
    ll p,b,n;
    map<ll,int> hash;
    
    ll fpow(ll x,ll b) {
        ll res=1;
        while(b) {
            if(b&1) {
                res*=x;
                res%=p;
            }
            b>>=1;
            x*=x;
            x%=p;
        }
        return res;
    }
    
    int main()
    {
        while(scanf("%lld%lld%lld",&p,&b,&n)!=EOF) {
            if(!(b%p)) {
                cout<<"no solution"<<endl;
                continue;
            }
            hash.clear();
            ll m=ceil(sqrt(p));
            ll ans=0;
            for(rint i=0;i<=m;i++) {
                if(!i) {
                    ans=n%p;
                    hash[ans]=i;
                    continue;
                }
                ans=ans*b%p;
                hash[ans]=i;
            }
            ans=1;
            bool flag=false;
            for(rint i=1;i<=m;i++) {
                ans=(ans*fpow(b,m))%p;
                if(hash[ans]) {
                    ans=i*m-hash[ans];
                    ans=(ans%p+p)%p;
                    printf("%lld
    ",ans);
                    flag=true;
                    break;
                }
            }
            if(!flag) 
                cout<<"no solution"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Unity SceneManager 对场景的操作
    Unity [Tooltip("")]
    Unity WWW下载图片并保存到Unity的Assets下
    C# 集合
    C# 枚举与switch用法
    C# String.Format方法
    C# Thread类 线程优先级
    Unity Gizmos可视化辅助工具
    anacanda
    异常和错误
  • 原文地址:https://www.cnblogs.com/qxyzili--24/p/11222847.html
Copyright © 2011-2022 走看看