BSGS exBGS

BSGS

求离散对数,即给出\(a,b,p\),求最小非负整数\(x\)满足:

\[a^x \equiv b \ (mod\ p) \]

其中\(gcd(a,p)=1\)

\(y=\sqrt{p}\)

1.把\(a\)\(0...y-1\)次幂\(*b\)塞到哈希表里。

2.枚举\(i\),看下是否存在\(a^{iy-j}\equiv b\ (mod\ p)\)

​ 即\(a^{iy}\equiv a^jb\ (mod\ p)\)

\(j\in [0,y-1]\),所以在哈希表里查一下就行了。

exBSGS

不保证\(gcd(a,p)=1\)

如果\(gcd(a,p)\nmid b\)则无解(写成方程就知道了)。

否则

\[a^{x-1}\frac{a}{d} \equiv \frac{b}{d} \ (mod\ \frac{p}{d}) \]

如果变成\(a^x=0\)就返回除的次数;如果\(gcd(a,p)=1\)就变成前面带个系数的\(BSGS\),也就\(a^iy\)变成\(Aa^iy\)而已。

洛谷模板题

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace Hash_Table{
	const int md=19260817;
	int T,tot,hd[md],nxt[100010],num[100010],val[100010],tim[100010];
	void add(int x,int y){
		int i=x%md;
		if (tim[hd[i]]<T) hd[i]=0;
		nxt[++tot]=hd[i],hd[i]=tot;
		num[tot]=x,val[tot]=y;
		tim[tot]=T;
	}
	int qry(int x){
		int i=x%md;
		if (tim[hd[i]]<T) return -1;
		for (int j=hd[i];j;j=nxt[j])
			if (num[j]==x) return val[j];
		return -1;
	}
}
int power(int x,int p,int md){
	int ret=1;
	for (;p;p>>=1,x=1ll*x*x%md)
		if (p&1) ret=1ll*ret*x%md;
	return ret;
}
int phi(int n){
	int ret=n;
	for (int i=2;i*i<=n;++i)
		if (n%i==0){
			ret=ret/i*(i-1);
			for (;n%i==0;n/=i);
		}
	if (n>1) ret=ret/n*(n-1);
	return ret;
}
int gcd(int x,int y){
	if (!y) return x;
	else return gcd(y,x%y);
}
int bsgs(int a,int b,int p,int A){
	++Hash_Table::T,Hash_Table::tot=0;
	int y=sqrt(p)+1,num=b,sum;
	for (int i=0;i<y;++i,num=1ll*num*a%p) Hash_Table::add(num,i);
	num=power(a,y,p),sum=1ll*A*num%p;
	for (int i=1,x;i<=y+1;++i,sum=1ll*sum*num%p){
		x=Hash_Table::qry(sum);
		if (x!=-1) return i*y-x;
	}
	return -1;
}
int exbsgs(int a,int b,int p){
	int ret=0,num=1;
	for (int d;;){
		d=gcd(a,p);
		if (d==1) break;
		if (b%d) return -1;
		p/=d,b/=d,++ret,num=1ll*num*a/d%p;
		if (num==b) return ret;
	}
	return ret+bsgs(a,b,p,num);
}
int a,b,p;
int main()
{
	for (scanf("%d%d%d",&a,&p,&b);a||b||p;){
		a%=p,b%=p;
		int x=exbsgs(a,b,p);
		if (x>=0) printf("%d\n",x);
		else puts("No Solution");
		scanf("%d%d%d",&a,&p,&b);
	}
	return 0;
}
posted @ 2020-05-12 09:38  _lhyyy  阅读(136)  评论(0编辑  收藏  举报