zoukankan      html  css  js  c++  java
  • exBSGS

    作用:求形如A^x==B(mod P)

    考虑由BSGS----->exBSGS

    BSGS:

    (A与P互质)A^phi(P)==1(mod P),A^0==1(modP),感性理解,是个循环,

    考虑分块,设A^(ky+b)==B(mod P)。

    即(A^y)^k*A^b==B(mod P)------>A^b==B*inv((A^y)^k)(mod P);设y==sqrt(P);(phi(P)更好,但是P也行,主要是懒)

    将A^g(0<=g<y)hash出,再每次判断即可。

    exBSGS:

    设 r=gcd(A,P),p=A/r,q=P/r;

    首先考虑无解的情况(B%r!=0&&B!=1)

    B=(r*p)^x+w*q*r=(r^x)*(p^x)+w*q*r=r*(r^(x-1))*p^x+r*q*w=r*(r^(x-1)*p^x+w*q);

    若B==1,A^0==1;

    所以,若(B%r!=0&&B!=1),则无解;

    使A,P互质需要除去公因数,设b=B/r,

    A*A^(x-1)==B(mod P)——>

    P=q,B=b;

    p*A^(x-1)==B(mod P)——>A^(x-1)=B*inv(p)(mod P);

    循环此过程,直至A与P互质即可。

    例题:https://www.luogu.org/problemnew/show/P4195

    #include<cstdio>
    #include<ctype.h>
    #include<iostream>
    #include<cmath>
    using namespace std;
    #define ll long long
    inline ll rd()
    {
        ll x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-') f=-f;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return x*f;
    }
    const int N=1e5,mod=99991;
    int P,vis[N],h[N],nxt[N],val[N];
    ll exgcd(ll &x,ll &y,ll a,ll b)
    {
        if(!b){x=1;y=0;return a;}
        int t=exgcd(x,y,b,a%b),w=x;x=y;y=w-(a/b)*x;
        return t;
    }
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll bsgs(ll a,ll b,ll w)
    {
        ll x,y,p=ceil(sqrt(P)),q,op=-1,i,j;exgcd(x,y,w,P);b=(b*x%P+P)%P;
        for(i=1,j=0;j<p;j++,i=i*a%P)  val[j+1]=i,x=i%mod,nxt[j+1]=h[x],h[x]=j+1;
        exgcd(x,y,i,P);q=(x%P+P)%P;
        for(i=b,j=0;j<=p;j++,i=i*q%P) {x=i%mod;for(y=h[x];y;y=nxt[y])if(val[y]==i)op=p*j+y-1;if(op!=-1) break;}
        for(i=1,j=0;j<p;j++,i=i*a%P) h[i%mod]=0;
        return op;
    }
    ll exbsgs(int a,int b)
    {
        ll c,k=0,w=1;if(b==1) return 0;
        while((c=gcd(a,P))>1){if(b%c) return -1;b/=c;P/=c;w=w*(a/c)%P;k++;if(w==b) return k;}
        return (c=bsgs(a,b,w))==-1?-1:c+k;
    }
    int main()
    {    
        while(1)
        {
            int a=rd(),b;ll c;P=rd();b=rd();if(!a&&!b&&!P) return 0;
            if((c=exbsgs(a,b))==-1) printf("No Solution
    ");else printf("%lld
    ",c);
        }
    }
  • 相关阅读:
    8.16
    8.6 总结
    Educational Codeforces Round 45 (Rated for Div. 2)
    Codeforces Round #487 (Div. 2)
    Codeforces Round #485
    codeforces Avito Code Challenge 2018
    MySQL索引知识面试题
    使用多线程优化复杂逻辑以及数据量多处理
    elasticsearch 和Ik 以及 logstash 同步数据库数据
    linux 安装elasticsearch步骤以及入的坑
  • 原文地址:https://www.cnblogs.com/LWL--Figthing/p/10802247.html
Copyright © 2011-2022 走看看