BZOJ2480 Spoj3105 Mod 数论 扩展BSGS

原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2480.html

题目传送门 - BZOJ2480

题意

  已知数 $a,p,b$ ,求满足 $a^x≡b \pmod p $ 的最小自然数 $x$ 。

  $a,p,b\leq 10^9$ 

题解

  ExBSGS模板题。

 

 

 

UPD(2018-09-10): 

  详见数论总结。 

  传送门 - https://www.cnblogs.com/zhouzhendong/p/Number-theory-Residue-System.html

 

 

代码

#include <bits/stdc++.h>
using namespace std;
int a,p,b;
int Pow(int x,int y,int mod){
	int ans=1;
	for (;y;y>>=1,x=1LL*x*x%mod)
		if (y&1)
			ans=1LL*ans*x%mod;
	return ans;
}
int gcd(int x,int y){
	return y?gcd(y,x%y):x;
}
struct hash_map{
	static const int Ti=233,mod=1<<16;
	int cnt,k[mod+1],v[mod+1],nxt[mod+1],fst[mod+1];
	int Hash(int x){
		int v=x&(mod-1);
		return v==0?mod:v;	
	}
	void clear(){
		cnt=0;
		memset(fst,0,sizeof fst);
	}
	void update(int x,int a){
		int y=Hash(x);
		for (int p=fst[y];p;p=nxt[p])
			if (k[p]==x){
				v[p]=a;
				return;
			}
		k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt,v[cnt]=a;
		return;
	}
	int find(int x){
		int y=Hash(x);
		for (int p=fst[y];p;p=nxt[p])
			if (k[p]==x)
				return v[p];
		return 0;
	}
	int &operator [] (int x){
		int y=Hash(x);
		for (int p=fst[y];p;p=nxt[p])
			if (k[p]==x)
				return v[p];
		k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt;
		return v[cnt]=0;
	}
}Map;
int ExBSGS(int A,int B,int P){
	A%=P,B%=P;
	int k=0,v=1;
	while (1){
		int g=gcd(A,P);
		if (g==1)
			break;
		if (B%g)
			return -1;
		k++,B/=g,P/=g,v=1LL*v*(A/g)%P;
		if (v==B)
			return k;
	}
	if (P==1)
		return k;
	int M=max((int)sqrt(1.0*P),1),AM=Pow(A,M,P);
	Map.clear();
	for (int b=0,pw=B;b<M;b+=1,pw=1LL*pw*A%P)
		Map.update(pw,b+1);
	for (int a=M,pw=1LL*v*AM%P;a-M<P;a+=M,pw=1LL*pw*AM%P){
		int v=Map.find(pw);
		if (v)
			return a-(v-1)+k;
	}
	return -1;
}
int main(){
	while (~scanf("%d%d%d",&a,&p,&b)&&(a||b||p)){
		int ans=ExBSGS(a,b,p);
		if (~ans)
			printf("%d\n",ans);
		else
			puts("No Solution");
	}
	return 0;
}

  

posted @ 2018-09-05 10:28  zzd233  阅读(221)  评论(0编辑  收藏  举报