求解 a^x≡b (mod c)
( x<c )
siz = sqrt( c )
a^( i*siz + j) ≡b (mod c)
a^j ≡ a^( - i* siz) *b (mod c)
枚举 j , 将 (j, a^j %c ) 存入map ;
枚举 i, 查询map的值 ( a^(-i *siz) *b %c
#include <iostream> #include <algorithm> #include <cstring> #include <unordered_map> #include <cmath> using namespace std; #define int long long #define INF 1e18 void gcd(int a,int b,int &d,int &x,int &y){ if(b==0){ d=a; x=1,y=0; return ; } gcd(b,a%b,d,y,x); y-=x*(a/b); } int BSGS(int A,int B,int C){ if(C==1){ if(!B) return A!=1; return -1; } if(B==1){ if(A) return 0; return -1; } if(A%C==0){ if(!B) return 1; return -1; } unordered_map<int,int> mp ; int siz=ceil(sqrt(C)); int D=1,s=1; // a^j %c for(int i=0;i<=siz-1;i++){ mp[s]=min(mp[s],i); s=(s*A)%C; } // a^(-i*siz)*b %c for(int i=0;i<=siz-1;i++){ int x,y; int g; gcd(D,C,g,x,y); x=(x*B%C+C)%C; if(mp.count(x)) return i*siz+mp[x]; D=(D*s)%C; } return -1; } signed main(){ int A,B,C; while(cin>>C>>A>>B){ int res=BSGS(A,B,C); if(res==-1) printf("no solution\n"); else printf("%lld\n",res); } }
手写hashmap
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define int long long
#define INF 1e18
void gcd(int a,int b,int &d,int &x,int &y){
if(b==0){
d=a; x=1,y=0; return ;
}
gcd(b,a%b,d,y,x); y-=x*(a/b);
}
struct HashMap{//哈希表
static const int Hash=999917,maxn=46340;
int num,link[Hash],son[maxn+5],next[maxn+5],w[maxn+5];
int top,Stack[maxn+5];
void clear(){//清空表
num=0;
while(top)
link[Stack[top--]]=0;
}
void add(int x,int y){//添加键值元素
son[++num]=y;
next[num]=link[x];
w[num]=INF;
link[x]=num;
}
bool count(int y){//判断表中是否有对应值
int x=y%Hash;
for(int j=link[x];j;j=next[j])
if(y==son[j])
return true;
return false;
}
int &operator [](int y){//获取键的对应值
int x=y%Hash;
for(int j=link[x];j;j=next[j])
if(y==son[j])
return w[j];
add(x,y);
Stack[++top]=x;
return w[num];
}
}mp ;
int BSGS(int A,int B,int C){
if(C==1){
if(!B)
return A!=1;
return -1;
}
if(B==1){
if(A)
return 0;
return -1;
}
if(A%C==0){
if(!B)
return 1;
return -1;
}
mp.clear();
int siz=ceil(sqrt(C));
int D=1,s=1;
// a^j %c
for(int i=0;i<=siz-1;i++){
mp[s]=min(mp[s],i);
s=(s*A)%C;
}
// a^(-i*siz)*b %c
for(int i=0;i<=siz-1;i++){
int x,y;
int g; gcd(D,C,g,x,y);
x=(x*B%C+C)%C;
if(mp.count(x))
return i*siz+mp[x];
D=(D*s)%C;
}
return -1;
}
signed main(){
int A,B,C;
while(cin>>C>>A>>B){
int res=BSGS(A,B,C);
if(res==-1)
printf("no solution\n");
else
printf("%lld\n",res);
}
}
浙公网安备 33010602011771号