zoukankan      html  css  js  c++  java
  • BSGS算法 (小步大步 Baby Step Gaint Step)

    当你要求满足:

    $$ A^x equiv B (mod P) $$

    的最小非负整数 x (gcd(A,P)==1)就可以用到 BSGS 了

    设 $ m=sqrt{P} $ 向上取整

    处理一下那个式子:

    $$ A^{i imes m-j} equiv B (mod P) $$
    $$ A^{i imes m} equiv B imes A^j (mod P) $$

    枚举 j(0到m),将 B*A^j 存入hash表里面
    枚举 i(1到m),从hash表中找第一个满足上面这条式子的 j
    x=i*m-j 即为所求 (感性理解)

    模板题: 【xsy 1754】 离散对数

    Description

            给定B,N,P,求最小的满足B^L=N(mod P)的非负正数L。保证gcd(B,P)=1。

    Input

            多组数据,每行三个空格隔开的整数P,B,N。

    Output

            对于每组数据,输出答案。如无解,则输出"no solution"

    CODE:

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<unordered_map>
     5 using namespace std;
     6 
     7 int p,a,b;
     8 
     9 int qpow(int x,int y){
    10     int ans=1;
    11     while(y){
    12         if(y&1)ans=1LL*ans*x%p;
    13         y>>=1,x=1LL*x*x%p;
    14     }
    15     return ans;
    16 }
    17 
    18 int BSGS(){
    19     unordered_map<int,int> mp;
    20     int m=ceil(sqrt(p)),tmp;
    21     tmp=b;
    22     for(int j=0;j<=m;j++)
    23         mp[tmp]=j,tmp=1LL*tmp*a%p;
    24     tmp=a=qpow(a,m);
    25     for(int i=1;i<=m;i++){
    26         if(mp.count(tmp))
    27             return i*m-mp[tmp];
    28         tmp=1LL*tmp*a%p;
    29     }
    30     return -1;
    31 }
    32 
    33 int main(){
    34     while(~scanf("%d%d%d",&p,&a,&b)){
    35         int ans=BSGS();
    36         if(~ans)printf("%d
    ",ans);
    37         else printf("no solution
    ");
    38     }
    39 }

    证明:

    有这样一条式子:

    证明了这个就搞定了

    处理一下这个式子:

     

    手头上的条件:gcd(A,P)=1
    欧拉定理:

    证完了OvO

    作者:ezoiLZH
    本文版权归作者和博客园所有,欢迎转载,只要写明原文链接即可(^_^)。
  • 相关阅读:
    http2
    JMH java基准测试
    java 线程池
    线程中断
    mybatis
    JDBC 线程安全 数据库连接池
    mysql string 列类型
    剖析nsq消息队列目录
    go微服务框架go-micro深度学习-目录
    详说tcp粘包和半包
  • 原文地址:https://www.cnblogs.com/ezoiLZH/p/9384603.html
Copyright © 2011-2022 走看看