Loading

题解 UVA10225 Discrete Logging

本题是一道 \(BSGS\) 裸题,用于求解高次同余方程,形如 \(a^x\equiv b(\mod p)\),其中 \(a\)\(p\) 互质(不互质还有 \(EXBSGS\))。

建议多使用 \(HASH\) 表,不要懒省事使 \(map\),数据大时会 \(T\) 飞。

\(AC \kern 0.4emCODE:\)

#include<bits/stdc++.h>
#define int long long
#define ri register int
#define p(i) ++i
#define H(x) ((x)%P+1)
using namespace std;
const int P=65537;
inline int read() {
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
struct HASH{
	struct Hash{
		int v,nxt,w;
	}H[P+7];
	int first[P+7],t;
	inline void init() {memset(first,0,sizeof(first));t=1;}
	inline void add(int v,int w) {
		int u=H(v);
		H[t].v=v;
		H[t].w=w;
		H[t].nxt=first[u];
		first[u]=t++;
	}
	inline int find(int v) {
		int u=H(v);
		for (ri i(first[u]);i;i=H[i].nxt) if (H[i].v==v) return H[i].w;
		return -1;
	}
}H;
inline int fpow(int x,int y,int p) {
	int res=1;
	while(y) {
		if (y&1) res=res*x%p;
		x=x*x%p;y>>=1;
	}
	return res;
}
inline int BSGS(int a,int b,int p) {
	H.init();b%=p;
	int t=ceil(sqrt(p));//注意这里,ceil(sqrt(p))与sqrt(p)+1没什么区别,但后者会WA,有可能是数据有锅,p非质数了。
	for (ri i(0);i<=t;p(i)) H.add(b,i),b=b*a%p;
	int c=1;a=fpow(a,t,p);
	if (!a) return !b?1:-1;
	for (ri i(0);i<=t;p(i)) {
		int j=H.find(c);
		if (j>=0&&i*t-j>=0) return i*t-j;
		c=c*a%p;
	}
	return -1;
}
signed main() {
	int p,a,b;
	while(scanf("%lld",&p)!=EOF) {
		a=read(),b=read();
		int ans=BSGS(a,b,p);
		if (ans==-1) printf("no solution\n");
		else printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2021-04-18 09:02  ナンカエデ  阅读(39)  评论(0编辑  收藏  举报