zoukankan      html  css  js  c++  java
  • 离散对数

    离散对数就是解方程:

    $$求最小的非负整数x满足,a^x equiv b(mod n)$$

    我们先谈论简单一点的,$gcd(a,n)=1$的情况:

    $$求最小的非负整数x满足,a^x equiv b(mod n),其中gcd(a,n)=1$$

    记$m=left lfloor sqrt{n} ight floor$

    那么$x$一定可以表示为$x=im+j(0leq ileq m,0leq j< m)$

    变形一下:

    $a^{im+j} equiv b(mod n)$

    $a^{im}equiv ba^{-j}(mod n)$

    我们先用一个map保存所有$ba^{-j}(0leq j< m)$的值,一共有$m$个。

    再枚举$a^{im}$,一共有$m$个,判断即可。

    但是要求逆元$a^{-j}$,要求$gcd(a,n)=1$

    我们现在来讨论$gcd(a,n)$不一定等于1的情况。

    $$求最小的非负整数x满足,a^x equiv b(mod n)$$

     我们想通过消因子,使得变成上面那种情况。

    设$d=gcd(a,n)$,且$a=a'd$,$n=n'd$

    变成:

    $(a'd)^x equiv b(mod n'd)$

    显然如果$b\%d eq 0$,那么一定没有解

    假设现在$b\%d=0$,$b=b'd$

    变成:

    $(a'd)^xequiv b'd(mod n'd)$

    $a'*(a'd)^{x-1} equiv b'(mod n')$

    $a'*a^{x-1} equiv b'(mod n')$

    很好,现在我们已经拿出来了一个因子$a'$了

    但是我们还是不能保证$gcd(a,n')=1$,但我们可以做多次,使得$gcd(a,n')=1$

    核心代码如下:

    LL c=1,cnt=0;
    while(1)
      {
          LL d=gcd(a,n);
          if(d==1)break;
          if(b%d!=0)return 0;
          c*=a/d;
          cnt++;
          n/=d;
          b/=d;
      }

    于是原问题变成:

    $$求最小的非负整数x满足,c imes a^{x-cnt}equiv b(mod n),其中gcd(a,n)=1$$

    很好,变成上面那种情况了。

    注意容易错的是,答案$x$有可能小于$cnt$,所以先要测试一下$0,1...,cnt-1$是否满足。

  • 相关阅读:
    量化投资:第3节 滑点策略与交易手续费
    量化投资:第2节 择时策略的优化
    量化投资: 第1节 择时策略的开发
    一步一步,完成sparkMLlib对日志文件的处理(1)
    JAVA接口与抽象类区别
    HDU1877 又一版 A+B
    HDU4548 美素数
    超级楼梯 HDU2041
    HDU2013 蟠桃记【递推】
    HDU1262 寻找素数对
  • 原文地址:https://www.cnblogs.com/maijing/p/4793115.html
Copyright © 2011-2022 走看看