• BSGS简叙


    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=1e6+7;
    const int mod=998244353;
    const int INF=0x3f3f3f3f;
    /*
       BSGS算法  b^l==n%p  求解最小的l
       不妨直接把l拆分成i*m-j,这样的话同余方程就变为b^(i*m)==n*b^j%p
       直接枚举j属于[0,m) m=ceil///向上取整(sqrt(p)) map记录当前的j的数值
       随后枚举i属于[0,m)查询map是否存在j满足且需要满足i*m>j=op[s]
       很显然这只是gcd(b,p)=1的情况,此时枚举只到了m-2与费马小定理对应
    */
    map<ll,ll>op;
    ll p,b,n;
    ll quick_pow(ll a,ll b,ll p)
    {
       ll ans=1;
       while (b)
       {
        if (b&1)///b为奇数
            ans=(ans*a)%p;
         a=(a*a)%p;///b为偶数
         b>>=1;
       }
       return ans;
    }
    ll BSGS(ll p,ll b,ll n)
    {
        ll m=ceil(sqrt(p));
        for (ll i=0,s=n;i<m;++i,s=s*1ll*b%p)///枚举的时候map记录位置
        {
            op[s]=i;
        }
        for (ll i=0,tmp=quick_pow(b,m,p),s=1ll;i<m;++i,s=s*1ll*tmp%p )///查找j
        {
            if (op.find(s)!=op.end())
            {
                if (i*m>=op[s])return i*m-op[s];
            }
        }
        return -1ll;
    }
    int main()
    {
        scanf("%lld%lld%lld",&p,&b,&n);///b^l==n%p
        ll cnt=BSGS(p,b,n);
        cnt==-1ll?cout<<"no solution"<<endl:cout<<cnt<<endl;
        return 0;
    }
    
    
    齐芒行,川锋明!
  • 相关阅读:
    Docker安装nexus
    docker常用操作备忘
    react-01
    SBT实操指南
    Play中JSON序列化
    SPARK安装一:Windows下VirtualBox安装CentOS
    SPARK安装三:SPARK集群部署
    SPARK安装二:HADOOP集群部署
    SLICK基础
    函数式编程
  • 原文地址:https://www.cnblogs.com/qimang-311/p/13403294.html
Copyright © 2020-2023  润新知