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 }
  • 相关阅读:
    突然想谈谈——我的软件测试入门
    js+rem动态计算font-size的大小,适配各种手机设备!
    iOS 如何打测试包,直接给测试人员使用(绝对的新手入门)
    去掉无用的多余的空格(string1.前后空格,2.中间空格)
    iOS 自定义键盘ToolBar(与键盘的弹出、收起保持一致)
    iOS上线...踩坑
    iOS10 导航条,这个二狗子变了...踩坑
    ios程序发布测试打包
    获取毫秒级时间戳
    弹簧动画效果(系统自带方法)
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/6719520.html
Copyright © 2011-2022 走看看