【TJOI 2007】可爱的质数

【题目】

传送门

题目描述:

给定一个质数 p p 2 p < 2 31 2≤p<2^{31} ),以及一个整数 b b 2 b < p 2≤b<p ),一个整数 n n 2 n < p 2≤n<p )。现在要求你计算一个最小的 l l ,满足 b l n (   m o d    p ) b^l ≡ n (\,\mathrm{mod}\; p)

输入格式:

输入仅一行,有 3 3 个整数,依次代表 p p b b n n

输出格式:

输出仅一行,如果有 l l 满足该要求,输出最小的 l l ,否则输出 “no solution”

样例数据:

输入
5 2 3

输出
3

备注:

【提示】

对于任意的质数 p p 和任意的整数 m m ,我们定义: b m b p 1 m b^{-m} ≡b^{p-1-m}


【分析】

这是一道 BSGS 的模板题。

具体的讲解就看我的另一篇博客 BSGS


【代码】

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<tr1/unordered_map>
#define ll long long
using namespace std;
using namespace tr1;
unordered_map<int,int>Hash;
int Power(int a,int b,int p)
{
	int ans=1;
	for(;b;b>>=1,a=(ll)a*a%p)if(b&1)ans=(ll)ans*a%p;
	return ans;
}
int BSGS(int a,int b,int p)
{
	b%=p;
	int i,t=ceil(sqrt(p));
	for(i=0;i<t;++i)
	  Hash[(ll)b*Power(a,i,p)%p]=i;
	a=Power(a,t,p);
	if(!a)  return b?-1:1;
	for(i=0;i<=t;++i)
	{
		int val=Power(a,i,p);
		int j=(Hash.find(val)==Hash.end())?-1:Hash[val];
		if(j>=0&&i*t-j>=0)  return i*t-j;
	}
	return -1;
}
int main()
{
	int a,b,p;
	scanf("%d%d%d",&p,&a,&b);
	int ans=BSGS(a,b,p);
	if(~ans)  printf("%d",ans);
	else  printf("no solution");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/forever_dreams/article/details/88749871