BSGS的一个拓展--模数为合数的做法

lsh留下来的遗产(虽然没看


ax==b(mod p) ax+kp==b g=gcd(a,p)bgagax1+kpg=bgagax1==bg(mod pg)ax1==bg(ag)1(mod pg)ax==b(mod m)x=x1b=bg(ag)1m=pg
这样下去直到能够bsgs为止
代码(bzoj2480)

#include<bits/stdc++.h>
#include<hash_map>
#define LL long long
using namespace std;
inline void splay(int &v){
    v=0;char c=0;int p=1;
    while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
    while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
    v*=p;
}
__gnu_cxx::hash_map<int,int>s;
int ksm(int a,int b,int c){
    int ans=1;
    while(b){
        if(b&1)ans=(LL)ans*a%c;
        b>>=1;a=(LL)a*a%c;
    }
    return ans;
}
int bsgs(int a,int b,int p){
    a%=p;b%=p;if(b==1)return 0;
    int cnt=0;LL t=1;
    for(int g=__gcd(a,p);g!=1;g=__gcd(a,p)){
        if(b%g)return -1;p/=g,b/=g,t=t*a/g%p;
        cnt++;if(b==t)return cnt;
    }
    s.clear();
    int k=sqrt(p)+1;LL now=b;
    for(int i=0;i<k;i++){
        s[now]=i;now=now*a%p;   
    }
    now=ksm(a,k,p);
    LL x=t;
    for(int i=1;i<=k+1;i++){
        x=x*now%p;
        if(s.count(x))return i*k-s[x]+cnt;
    }
    return -1;
}
int main(){
    while(1){
        int a,b,p;splay(a),splay(p),splay(b);
        if(p==1){
            puts("0");continue;
        }
        if(!p)break;int x=bsgs(a,b,p);
        if(!~x)puts("No Solution");
        else printf("%d\n",x);
    }
}
阅读更多
版权声明:233333333333333333333333333333333333333333 https://blog.csdn.net/lcrtest/article/details/51657025
文章标签: 题解 bsgs 算法
上一篇bzoj 4461: [Jsoi2013]美丽家园
下一篇bzoj 4028 [HEOI2015]公约数数列
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭