zoukankan      html  css  js  c++  java
  • 拓展BSGS算法(先挖个坑,督促自己)

    回顾一下朴素的BSGS算法,只能用来解p为质数情况下的a^x≡b(mod p)

    p不为质数呢,那就要用扩展BSGS算法了。

    其实扩展BSGS算法只是在原有BSGS算法上加了一个能将原方程转移为能用朴素BSGS解决的算方程。

    先看这样一个性质:

    A%P=B

    则可以表示为A-P*x=B

    假设d=gcd(A,P),且B%d=0

    (A/d)%(P/d)=B/d

    所以,只要d=gcd(A,P)!=1,且B%d=0,就能一直化简。

    过程中,若B%d!=0,则无解。

    于是原方程可以表示为a^(x-js)*(a^js/s)≡b/s(mod (p/s))(s为原来求的每个因子di的乘积,js为消除因子的次数)

    => a^(x-js)≡b*a^(-js)(mod (p/s))

    换元:x‘=x-js,b’=b*a^(-js),p'=p/s

    得 a^(x')≡b'(mod p')

    用BSGS解得x',原方程的解为x=x'+js

    PS:a^(-js)可以用扩欧求逆元,但有个玄学做法的BSGS是不需要求逆元的,下面是那个玄学做法的程序

    ll exbsgs(ll a,ll b,ll p){
      if(b==1)return 0;
      ll js=0;
      ll k=1;
      ll cc;
        while((cc=gcd(a,p))!=1){
        if(b%cc!=0){
          return -1;
        }
        else{
          js++;
          b/=cc;
          p/=cc;
          k=k*(a/cc)%p;  
          if(b==k)return js;
        }
      }
      ll m=ceil(sqrt(p));
      Hash.clear();
      cc=ksm(a,m);
      ll ss=b;
      Hash[ss]=0;
      for(int i=1;i<=m;i++){
        ss=ss*a%p;
        Hash[ss]=i;
      }
      for(int i=1;i<=m;i++){
        k=k*cc%p;
        if(Hash.count(k)){
          return i*m-Hash[k]+js;//!!这里是-,不是+(玄学操作,我也不懂)
        }
      }  
      return -1;
    }

     放道板题Poj 3243 Clever Y   题目传送门:http://poj.org/problem?id=3243

    注意:貌似(其实就是)用map存会TLE,所以最好用哈希表。

  • 相关阅读:
    document.compatMode的CSS1compat
    js自运行函数
    Sublime Text 3 入门(插件控制台安装)
    javascript 面向对象技术
    jQuery ui 中文日历
    js给数字加三位一逗号间隔的两种方法(面试题)
    android eclipse集成环境
    中科红旗倒下,谁来挑战windows
    在网站制作中随时可用的10个 HTML5 代码片段
    IE6/IE7中li底部4px的Bug
  • 原文地址:https://www.cnblogs.com/chenjingqi/p/8894031.html
Copyright © 2011-2022 走看看