求解离散对数——BSGS算法の板子

BSGS这玩意儿好像用的不是很多?好像除了POJ和HDU有两道题,然后就是SDOI的两个题了。。然后关于这玩意儿正确性的很多证明ATP都不是很懂。。这里只是解释一下它的实现过程。。

BSGS

BSGS算法(Baby Step Gaint Step)是用于求解离散对数(即 ALB(mod C) 中的最小的 L )的一种算法。它的实质是一种优化的枚举算法,但是它通过数学分析缩小了枚举的范围,一般在 O(n) O(nlogn) (如果使用STL的map作为哈希表)的时间复杂度内就能出解。

普通的BSGS算法要求 A,C 互质。这里先贴板子再解释。。。(其中powww(a,t,Mod)是计算快速幂 at % Mod 的过程)

void BSGS(LL A,LL B,LL C){
    LL m=ceil(sqrt(C)),k=B%C,am,x;
    bool end=false;
    if (B%C==0){
        printf("No Solution\n");
        return;
    }
    hash.clear();
    hash[k]=0;
    am=powww(A,m,C);
    for (int j=1;j<=m;j++){
        k=k*A%C;hash[k]=j;
    }
    x=1;
    for (int i=1;i<=m;i++){
        x=x*am%C;
        if (hash[x]!=0){
            printf("%I64d\n",((i*m-hash[x]+cnt)%C+C)%C);
            end=true;
            return;
        }
    }
    if (end==false)
      printf("No Solution\n");
}

对于要求的式子 ALB(mod C) ,首先我们设定一个值 M ,并且设 L=iMj 。那么原来的式子就能表示成 AiMjB 。显然我们可以把 Aj 移到等式的右侧变成

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值