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))

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

exBSGS

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

如果(gcd(a,p) mid 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
",x);
		else puts("No Solution");
		scanf("%d%d%d",&a,&p,&b);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/zzqtxdy/p/12874298.html