其他分享
首页 > 其他分享> > P3846 [TJOI2007] 可爱的质数/【模板】BSGS

P3846 [TJOI2007] 可爱的质数/【模板】BSGS

作者:互联网

稍后更新

题面

题意:

给定\(p,b,n\),求满足\(b^{x}\equiv n\ (mod\ p)\)的最小的\(x\)的值

算法分析:

根据题意我们很容易想到这个题用\(BSGS\)(大步小步算法或北上广深或拔山盖世)来做,\(BSGS\)就是用来处理这一类问题的

\(BSGS\)中的\(p\)为质数

实现:

我们考虑柿子\(b^{x}\equiv n\ (mod\ p)\)

根据费马小定理\(a^{p-1}\equiv 1\ (mod\ p)\)(证明在我的另一篇博客里有提到过),且\(a^{0}\equiv 1\ (mod\ p)\)

我们可以发现\(a^{x}\equiv n\ (mod\ p)\) 中,当\(x \in [0,p-1)\)时,\(a^{x} mod \ p\) 构成了\(mod\ p\)的一个完全剩余系

我们就可以发现\([0, p-2]\)是一个循环节,且每个循环节都会构成一个\(mod\ p\) 的完全剩余系

所以我们只需要考虑\(x\in [0,p-2]\)中,\(a^{x}\equiv n\ (mod\ p )\)

然后我们设$m= $

#include<bits/stdc++.h>
using namespace std;
long long n, b, p, m, ans, now, st;
map<long long, int> mp;
long long ksm(long long x, long long y){
	long long res = 1;
	while(y){
		if(y & 1) res = (res * x) % p;
		x = (x * x) % p;
		y >>= 1;
	}
	return res % p;
}
int main(){
	mp.clear();
	scanf("%d %d %d", &p, &b, &n);
	if(b % p == 0){
		printf("no solution\n");
		return 0;
	}
	m = ceil(sqrt(p));
	now = n % p;
	mp[now] = 0;
	for(int i = 1; i <= m; i ++){
		now = (now * b) % p;
		mp[now] = i;
	}
	st = ksm(b, m);
	now = 1;
	for(int i = 1; i <= m; i ++){
		now = (now * st) % p;
		if(mp[now]){
			ans = i * m - mp[now];
			printf("%lld\n", ((ans % p) + p) % p);
			return 0;
		}
	}
	printf("no solution\n");
	return 0;
}

标签:BSGS,now,P3846,res,质数,long,TJOI2007,mod,equiv
来源: https://www.cnblogs.com/wsdslll/p/13494183.html