• 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);
        }
    }
  • 相关阅读:
    Visual C#动态生成控件
    (转)GridView 72般绝技
    ASP.NET给DataGrid,Repeater等添加全选批量删除等功能(转)
    JS操作字符串
    在IE中调试客户端脚
    一组很棒的button样式 (转)
    c#实现随机字符串(不包含数字)
    1996年4月全国计算机等级考试二级C语言笔试试题
    ASP.NET 2.0站点登录、导航与权限管理 转
    1996年9月全国计算机等级考试二级C语言笔试试题
  • 原文地址:https://www.cnblogs.com/LWL--Figthing/p/10802247.html
Copyright © 2020-2023  润新知