zoukankan      html  css  js  c++  java
  • 【知识点】BSGS

    Big-Step-Giant-Step:

    用于解形如$a^{x}equiv b(mod p)$式的方程。

    考虑分块,令$n=lceil sqrt{p} ceil,x=rn-s$,则有

    $a^{rn-s}equiv b(mod p)$

    $a^{rn}equiv ba^{s}(mod p)$

    分别在$[1,n]$的范围内枚举$r,s$并用$map$记录模数即可。

    复杂度$O(sqrt{p})$。

    #include<bits/stdc++.h>
    #define maxn 200005
    #define maxm 500005
    #define inf 0x7fffffff
    #define ll long long
    #define rint register ll
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    ll p,y,z,m; map<ll,ll> M;
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline ll power(ll a,ll b){
        ll ans=1;
        while(b){
            if(b&1) ans=ans*a%p;
            a=a*a%p,b>>=1;
        }
        return ans;
    }
    
    int main(){
        p=read(),y=read(),z=read(),m=ceil(sqrt(p));
        for(ll i=0,now=1;i<=m;i++,now=now*y%p) M[z*now%p]=i;
        ll ans=1ll<<62,pw=power(y,m);
        for(ll i=0,now=1;i<=m;i++,now=now*pw%p){
            if(M[now] && i*m-M[now]>=0) ans=min(ans,i*m-M[now]);
        }
        if(ans==(1ll<<62)) printf("no solution
    ");
        else printf("%lld
    ",ans);
        return 0;
    }
    BSGS

    扩展BSGS:

    容易发现上面的移项需要满足$gcd(a,p)=1$,若不满足该条件则需要转化。

    我们令$gcd(a,p)=g$,将整个式子除$g$,得到$frac{a}{g}a^{x-1}equiv frac{b}{g}(mod frac{p}{g})$。

    若$g mid b$则无解,否则检查此时$a,frac{p}{g}$是否互质,若不互质则继续除。

    最终计算互质时的答案,再加上除的次数$k$即可。

    #include<bits/stdc++.h>
    #define maxn 200005
    #define maxm 500005
    #define inf 0x7fffffff
    #define ll long long
    #define rint register ll
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    unordered_map<ll,ll> M;
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline ll gcd(ll a,ll b){return (b==0)?a:gcd(b,a%b);}
    inline ll power(ll a,ll b,ll p){
        ll ans=1;
        while(b){
            if(b&1) ans=ans*a%p;
            a=a*a%p,b>>=1;
        }
        return ans;
    }
    
    int main(){
        while(1){
            ll a=read(),p=read(),b=read(),k=0,x=1;
            if(a==0 && b==0 && p==0) break;
            bool flag=1;
            while(1){
                ll g=gcd(a,p); if(g==1) break;
                if(b%g!=0){printf("No Solution
    ");flag=0;break;}
                k++,p/=g,b/=g,x=x*(a/g)%p;
                if(x==b){printf("%lld
    ",k);flag=0;break;}
            }
            if(!flag) continue;
            M.clear(),a%=p,b%=p;
            ll n=ceil(sqrt(p)),ans=1ll<<62,now=1;
            for(rint i=0;i<=n;i++,now=now*a%p) M[b*now%p]=i;
            now=1; ll pw=power(a,n,p);
            for(rint i=0;i<=n;i++,now=now*pw%p){
                ll t=x*now%p;
                if(M[t] && i*n-M[t]+k>=0) ans=min(ans,i*n-M[t]+k);
            }
            if(ans==1ll<<62) printf("No Solution
    ");
            else printf("%lld
    ",ans);
    
        }
        return 0;
    }
    扩展BSGS
  • 相关阅读:
    Python开发【Part 2】:初识Python
    Python开发
    python-软件开发目录规范
    python-常用模块-re正则
    python-常用函数模块学习-logging模块
    python-常用函数模块学习-subprocess
    python-常用函数模块hashlib加密
    python-常用函数模块学习
    python-函数-内置方法
    python-函数
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13229515.html
Copyright © 2011-2022 走看看