lsh留下来的遗产(虽然没看
求
ax==b(mod p)得 ax+k∗p==b设 g=gcd(a,p),那么bg为整数得agax−1+kpg=bgagax−1==bg(mod pg)ax−1==bg(ag)−1(mod pg)ax′==b′(mod m′)其中x′=x−1b′=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);
}
}