zoukankan      html  css  js  c++  java
  • BSGS算法(大小步算法)

    $BSGS$ 算法 $Baby Steps Giant Steps$.

    致力于解决给定两个互质的数 $a, p$ 求一个最小的非负整数 $x$ 使得 $a^xequiv b(mod p)$ 其中 $b$ 为任意正整数,$2≤a<p$,$2≤b<p$

    该算法使用的原理与欧拉定理有关,其中$a, p$互质

                      $a^{phi (p)}equiv 1(mod p)$

    又因为

                      $a^0equiv 1(mod p)$

    所以$0到phi p$是一个循环节,也就是说该算法最多查找$phi (p)$次就可以找到答案,否则就无解。

    设$x=im-k$其中$0≤k≤m$ 原式变为 

                      $a^{im-k}equiv b(mod p)$

    两边乘以$a^k$得到

                      $a^{im}equiv a^kb(mod p)$

    然后我们可以拆成左右两部分分别进行枚举$i$和$k$。

    ①先枚举$k$,把对应的结果$a^kb$和对应的$k$放入$map$中,$map\_name[a^kb]=k$。$(k from 0 to m)$

    ②然后枚举$i$,把得到的结果$a^{im}$在$map$中进行查找,如果$map\_name.count(a^{im})$可以找到,则输出此时的$im-k$即可。($i from 1 to m$)

    如果超出查找范围还没找到,则无解。

    这里注意下,对$a^{im}$枚举时,要先快速幂预处理出来$a^m$,然后枚举$i$即可。

    算法时间复杂度为$O(max(m, phi (p)/m))$.

    最坏情况为$p$为质数$phi (p)=p-1$

    此时将$m$取$sqrt p$为最小,时间复杂度为$O(sqrt p)$。

    $m$取$sqrt p+1$或$ceil(sqrt p)$。

    例题:P3846 [TJOI2007]可爱的质数

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int n, p, b;
    
    unordered_map<ll, int> vis;
    inline ll fp( ll a, ll b ){
        a %= p;
        ll res = 1;
        while( b ){
            if( b&1 ) res = res*a%p;
            b >>= 1;
            a = a*a%p;
        }
        return res;
    }
    
    int main()
    {
    
        ios::sync_with_stdio(0);
    
        cin.tie(0); cout.tie(0);
        cin >> p >> b >> n;
        ll m = ceil(sqrt(p));   /*算法复杂度O( max(m, phi(p)/m) ) 所以m取ceil(sqrt(p))最快O(sqrt(p)) */
        ll tmp = n;
        for( int k=0; k<=m; k++,(tmp*=b)%=p ){
            vis[tmp] = k;
        }
        ll t = fp(b, m); tmp = t;
        bool flag = 0;
        for( int i=1; i<=m; i++, tmp=tmp*t%p ){
            if( vis.count(tmp) ){
                flag = 1;
                cout << i*m-vis[tmp] << endl;
                break;
    
            }
        }
        if(!flag) cout << "no solution" <<endl;
    
        return 0;
    }
  • 相关阅读:
    数组作为方法参数时的一些意外情况
    pack://application:,,,/
    WPF 使用WinForm Chart控件
    WPF 后台绑定样式
    在转换为 UTC 时大于 DateTime.MaxValue 或小于 DateTime.MinValue 的 DateTime 值无法系列化为 JSON
    LINQ_to_SQL语法及实例大全
    C#编码好习惯,献给所有热爱c#的同学
    C#中OpenFileDialog的使用
    NET 2.0(C#)调用ffmpeg处理视频的方法
    SQLite Mysql 模糊查找(like)
  • 原文地址:https://www.cnblogs.com/WAautomaton/p/12048212.html
Copyright © 2011-2022 走看看