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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值