【洛谷P3846】可爱的质数

题目

题目链接:https://www.luogu.com.cn/problem/P3846
给出\(a,b,p\),保证\(p\)是质数,求一个最小的\(k\)满足\(a^k\equiv n(\rm \mod\ p)\)

思路:

\(BSGS\)模板题。果然我菜到只会敲模板了吗。
\(t=\sqrt{p},k=i\times t-j\),那么移项得\((a^t)^i \equiv b\times a^j\),其中\(i,j\leq t\)
那么我们可以把\(b\times a^j(j\in [0,t])\)插入一个\(hash\)表内,然后再枚举\(i\)求出\((a^t)^i\),如果这个值在\(hash\)表内有出现,那么答案就是\(i\times t-hash[]\)
时间复杂度\(O(\sqrt{p})\)。由于\(hash\)表我使用了\(map\),实际上还要多一个\(log\)

代码

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

int a,b,p,t;
map<int,int> hash;

int power(ll x,ll k,int MOD)
{
	ll ans=1;
	for (;k;k>>=1,x=x*x%MOD)
		if (k&1) ans=ans*x%MOD;
	return (int)ans;
}

int main()
{
	scanf("%d%d%d",&p,&a,&b);
	t=sqrt(p)+1;
	for (int i=0;i<=t;i++)
		hash[1LL*b*power(a,i,p)%p]=i;
	a=power(a,t,p);
	for (int i=1;i<=t;i++)
	{
		int val=power(a,i,p);
		if (hash[val])
			return !printf("%lld",(1LL*(i*t-hash[val])%p+p)%p);
	}
	printf("no solution");
	return 0;
}
posted @ 2020-01-27 11:31  stoorz  阅读(181)  评论(0编辑  收藏  举报