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,所以最好用哈希表。

  • 相关阅读:
    负载(Load)分析及问题排查
    MySQL 数据库规范--调优篇(终结篇)
    AbstractQueuedSynchronizer
    为什么String被设计为不可变?是否真的不可变?
    数据库 分库 分表 分区
    Oracle 数据库知识汇总篇
    小知识:如何判断数据文件的高水位线
    RHEL7安装11204 RAC的注意事项
    案例:DG主库未设置force logging导致备库坏块
    Oracle 11g RAC之HAIP相关问题总结
  • 原文地址:https://www.cnblogs.com/chenjingqi/p/8894031.html
Copyright © 2011-2022 走看看