• BSGS及扩展BSGS模板


    BSGS

    #include <iostream>//poj2417
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    
    using namespace std;
    const int maxint=((1<<30)-1)*2+1;
    
    int A,B,C;
    struct Hashmap{
        static const int Ha=999917,maxe=46340;
        int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5];
        int top,stk[maxe+5];
        void clear() {E=0;while(top) lnk[stk[top--]]=0;}
        void Add(int x,int y){son[++E]=y;nxt[E]=lnk[x];w[E]=maxint;lnk[x]=E;}
        bool count(int y)
        {
            int x=y%Ha;
            for(int j=lnk[x];j;j=nxt[j])
                if(y==son[j]) return true;
            return false;
        }
        int& operator [] (int y)
        {
            int x=y%Ha;
            for(int j=lnk[x];j;j=nxt[j])
                if(y==son[j]) return w[j];
            Add(x,y);stk[++top]=x;return w[E];
        }
    };
    Hashmap f;
    
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(!b) {x=1;y=0;return a;}
        int r=exgcd(b,a%b,x,y),t=x;x=y;y=t-(a/b)*y;
        return r;
    }
    
    int BSGS(int A,int B,int C)
    {
        if(C==1) if(!B) return A!=1; else return -1;
        if(B==1) if(A) return 0; else return -1;
        if(A%C==0) if(!B) return 1;else return -1;
        int m=ceil(sqrt(C)),D=1,Base=1;f.clear();
        for(int i=0;i<=m-1;i++)//先把A^j存进哈希表
        {
            f[Base]=min(f[Base],i);
            Base=((ll)Base*A)%C;
        }
        for(int i=0;i<=m-1;i++)
        {
            int x,y,r=exgcd(D,C,x,y);
            x=((ll)x*B%C+C)%C;//扩欧求A^j
            if(f.count(x)) return i*m+f[x];//找到解
            D=((ll)D*Base)%C;
        }
        return -1;
    }
    
    int main()
    {
        while(~scanf("%d%d%d",&C,&A,&B))
        {
            int ans=BSGS(A,B,C);
            if(ans==-1) printf("no solution
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }

    扩展BSGS

    #include <iostream>//poj3243
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    
    using namespace std;
    const int maxint=((1<<30)-1)*2+1;
    
    int A,B,C;
    struct Hashmap{
        static const int Ha=999917,maxe=46340;
        int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5];
        int top,stk[maxe+5];
        void clear() {E=0;while(top) lnk[stk[top--]]=0;}
        void Add(int x,int y){son[++E]=y;nxt[E]=lnk[x];w[E]=maxint;lnk[x]=E;}
        bool count(int y)
        {
            int x=y%Ha;
            for(int j=lnk[x];j;j=nxt[j])
                if(y==son[j]) return true;
            return false;
        }
        int& operator [] (int y)
        {
            int x=y%Ha;
            for(int j=lnk[x];j;j=nxt[j])
                if(y==son[j]) return w[j];
            Add(x,y);stk[++top]=x;return w[E];
        }
    };
    Hashmap f;
    
    int gcd(int a,int b){
        if(!b) return a;
        else return gcd(b,a%b);
    }
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(!b) {x=1;y=0;return a;}
        int r=exgcd(b,a%b,x,y),t=x;
        x=y;y=t-(a/b)*y;
        return r;
    }
    
    int exBSGS(int A,int B,int C)
    {
        if(C==1) if(!B) return A!=1;else return -1;
        if(B==1) if(A) return 0;else return -1;
        if(A%C==0) if(!B) return 1;else return -1;
        int r,D=1,num=0;
        while((r=gcd(A,C))>1)
        {
            if(B%r) return -1;num++;
            B/=r;C/=r;D=((ll)D*A/r)%C;
        }
        for(int i=0,now=1;i<num;i++,now=((ll)now*A)%C)
        {
            if(now==B) return i;
        }
        int m=ceil(sqrt(C)),Base=1;f.clear();
        for(int i=0;i<=m-1;i++)
        {
            f[Base]=min(f[Base],i);
            Base=((ll)Base*A)%C;
        }
        for(int i=0;i<=m-1;i++)
        {
            int x,y,r=exgcd(D,C,x,y);
            x=((ll)x*B%C+C)%C;
            if(f.count(x)) return i*m+f[x]+num;
            D=((ll)D*Base)%C;
        }
        return -1;
    }
    
    int main()
    {
        while(~scanf("%d%d%d",&A,&C,&B))//A^y mod C=B
        {
            if(!A&&!B&&!C) break;
            int ans=exBSGS(A,B,C);
            if(ans==-1) printf("No Solution
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    [HDU3247]Resource Archiver
    [POJ2243]考研路茫茫——单词情结
    [POJ2778]DNA Sequence
    [bzoj3670] [Noi2014]动物园
    [bzoj3786] 星系探索
    [bzoj1493] [NOI2007]项链工厂
    postgreSQL的设置自增主键初始值
    postgreSQL绝对值
    GitHub上新建或删除仓库Repository
    Intellij Idea上传本地项目到Git
  • 原文地址:https://www.cnblogs.com/Fy1999/p/9786240.html
Copyright © 2020-2023  润新知