zoukankan      html  css  js  c++  java
  • BSGS与exBSGS学习笔记

    (BSGS)用于解决这样一类问题:

    求解(A^x ≡B(modP))的最小(x),其中(P)为质数。

    这里我们采用分块的方法,把(x)分解为(i *t-b)(其中(t)是分块大小) 。根据模意义下逆元的性质,(x)的大小一定(<=phi(p))(p - 1),所以经过移项和进行存在性对比,我们就可以(O(N))求出答案。

    int BSGS (int A, int B, int P) {
        int t = (int) ceil (sqrt (P));
        for (int j = 0; j < t; ++j) {
            mp[_mul (B, _pow (A, j, P), P)] = j;
            //mp[ B * A ^ j ] = j; 
        }
        A = _pow (A, t, P);
        for (int i = 1; i <= t; ++i) {
            int val = _pow (A, i, P);
            //val = A^{i*t};
            int j = mp.find (val) == mp.end () ? -1 : mp[val];  
            if (j >= 0) {
                return i * t - j;
            }
        }
        return -1;
    } 
    

    上面这份代码中其实还可以把快速幂的(log)优化掉,可能会被卡常。

    几个要注意的关键点:

    • 避免快速幂
    • 优化快速乘
    • 小心取模和(longlong)
    • (p)一定要是质数!
    • 建议手写哈希不然会多一个(log)(unordered\_map)是不允许使用的)

    (exBSGS)其实就是一个简单的扩展,把情况扩展到了(p)不是质数的情况,这种情况我们要先把(P)(A)化为互质的状态。也就是说:对(A)(P)(gcd)直到其互质为止,从而化为如下形式:

    [(A/d)^{cnt} * A^{x}≡B/d^{cnt} (mod P/d^{cnt}) ]

    其中,当(B)不能被二者的(gcd)整除时,就意味着原方程无解。

    几个注意点:

    • 前面的((A/d)^{cnt})同样需要统计进去
    • 要使用(exgcd)求解,因为可能不存在逆元。
    • 可能存在(x==0)的情况,记得特判
    • 快速乘,(longlong),取模,务必小心。
    int exbsgs (int A, int B, int p) {
        if (B == 1) return 0;
        int _gcd, cnt = 0, res = 1;
        while ((_gcd = gcd (A, p)) != 1) {
            if (B % _gcd) return -1;
            B /= _gcd, p /= _gcd, ++cnt;
            res = ((res % p) * (A / _gcd)) % p;
            if (res == B) return cnt;
        }
        int t = sqrt (p) + 1, tmp = 1;
        Hash.clear ();
        for (int i = 0; i < t; ++i) {
            Hash[(tmp * B) % p] = i;
            tmp = (tmp * A) % p;
        }
        res = (res * tmp) % p;
        for (int i = 1; i <= t; ++i) {
            if (Hash.find (res) != Hash.end ()) {
                return i * t - Hash[res] + cnt;
            }
            res = (res * tmp) % p;
        }
        return -1;
    }
    
  • 相关阅读:
    Uploader 文件上传
    filters过滤器的使用
    Calendar中遇到的问题
    中科院之旅
    Python基础教程:列表推导式详解
    不会也要知道的,Python四种实现排序的方法
    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
    2021字节跳动校招秋招算法面试真题解题报告--leetcode206 反转链表,内含7种语言答案
    求协方差
    国外卡组织的 交换费-interchangefee(发卡行服务费) 和 银联对比
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10489374.html
Copyright © 2011-2022 走看看