zoukankan      html  css  js  c++  java
  • 离散对数的求解(bsgs)

    bsgs算法

    主要用来解决${A^x} = B(mod C)$(c是质数),都是整数,已知A、B、C求x。

    例:poj 2417 Discrete Logging

    具体步骤如下:

    先把$x = i*m - j$,其中$m = ceil(sqrt C )$,(ceil是向上取整)。

    这样原式就变为${A^{(i*m - j)}} = B(mod C)$,

    再变为${A^j}*B = {A^{(m*i)}}(mod C)$。

    枚举j(范围0-m),将${A^j}*B$存入hash表

    枚举i(范围1-m),从hash表中寻找第一个满足${A^j} * B = {A^{(m * i)}}(mod C)$。

    此时$x = i*m - j$即为所求。

    在网上看到的其他题解大多用的是$x = i*m + j$,也可以做,只是会牵扯的求逆元,所以比较麻烦。使$x=i*m-j$就可以轻松避免这个问题了。

    那么肯定有人会有疑问为何只计算到$m = ceil(sqrt C )$就可以确定答案呢?

    $x = i*m - j$ 也就是x 的最大值不会超过p,那超过p的怎么办 ?

    有一个公式  ${a^{kmod (p - 1)}} = {a^k}(mod p)$    这个公式的推导需要用到费马小定理

    $kmod p - 1$可以看做 $k - m*(p - 1)$ ,原式可化成  ${a^k}/{({a^{(p - 1)}})^m} = {a^k}(mod p)$ 

    根据费马小定理 ${a^{(p - 1)}} = 1(mod p)$其中p为质数 ,a,p 互质,可得${a^k}/{1^m} = {a^k}(mod p){a^k} = {a^k}(mod p)$得证

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<map>
     7 using namespace std;
     8 typedef long long ll;
     9 ll q=2147483647,a=3,yy,y2,m,ans,t;
    10 map<ll,int>mp;
    11 ll mod_pow(ll x,ll n,ll mod){
    12     ll res=1;
    13     while(n>0){
    14         if(n&1)    res=res*x%mod; 
    15         x=x*x%mod;
    16         n>>=1;
    17     }
    18     return res;
    19 }
    20 
    21 int main(){
    22     while(~scanf("%lld%lld",&yy,&y2)){
    23         mp.clear();
    24         m=ceil(sqrt(q));
    25         for(ll i=0;i<=m;i++){
    26             if(i==0){
    27                 ans=yy%q;
    28                 mp[ans]=i;
    29                 continue;
    30             }
    31             ans=ans*a%q;
    32             mp[ans]=i;
    33         }
    34         bool flag=false;
    35         ans=1;
    36         t=mod_pow(a,m,q);
    37         
    38         
    39         for(int i=1;i<=m;i++){
    40             ans=ans*t%q;
    41             if(mp[ans]){
    42                 ll temp=i*m-mp[ans];
    43                 ll rr=mod_pow(y2,temp,q);
    44                 printf("%lld
    ",rr);
    45                 flag=true; 
    46                 break;
    47             }
    48         }
    49         if(!flag){
    50         printf("No Solution
    "); 
    51         }
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    程序员修炼之道读书笔记02
    程序员修炼之道读书笔记01
    2021年1月30日 体温上报app03(百度API的获取和配置方法)
    2021年1月28日 体温上报app02
    2021年1月27日 体温上报app01
    2021年1月26日 sqlite数据库
    2021年1月25日 列表与适配器
    16.CSS margin用法
    14.CSS 块级元素与行内元素
    12.CSS 简单认识margin
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/6719520.html
Copyright © 2011-2022 走看看