BZOJ 3239 Discrete Logging Baby-Step-Giant-Step

题目大意:给定P,B,N,求最小的L使B^L≡N (mod P) (P是质数)

裸的BSGS。。。 练练手吧- -

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
#define INF 0x3f3f3f3f
using namespace std;
typedef pair<long long,long long> abcd;
long long A,B,C;
namespace Hash_Set{
	struct List{
		List *next;
		int key,val;
		List(List *_,int __):
			next(_),key(__),val(INF) {}
	}*head[M];
	int tim[M],T;
	inline void Clear()
	{
		++T;
	}
	int& Hash(int key)
	{
		int x=key%M;
		if(tim[x]!=T)
			tim[x]=T,head[x]=0x0;
		List *temp;
		for(temp=head[x];temp;temp=temp->next)
			if(temp->key==key)
				return temp->val;
		head[x]=new List(head[x],key);
		return head[x]->val;
	}
}
abcd EXGCD(long long x,long long y)
{
	if(!y) return abcd(1,0);
	abcd temp=EXGCD(y,x%y);
	return abcd(temp.second,temp.first-x/y*temp.second);
}
int EXBSGS()
{
	using namespace Hash_Set;
	int i;
	long long A_m,D,m=(int)ceil(sqrt(C)+1e-7);
	Clear();
	for(i=0,A_m=1;i<m;i++,(A_m*=A)%=C)
	{
		int &temp=Hash(A_m);
		temp=min(temp,i);
	}
	for(i=0,D=1;i<=m;i++,(D*=A_m)%=C)
	{
		abcd temp=EXGCD(D,C);
		long long x=(temp.first*B%C+C)%C;
		if(Hash(x)!=INF)
			return i*m+Hash(x);
	}
	return -1;
}
int main()
{
	while(cin>>C>>A>>B)
	{
		int ans=EXBSGS();
		if(!~ans) puts("no solution");
		else printf("%d\n",ans);
	}
	return 0;
}



你可能感兴趣的:(bzoj,BSGS,BZOJ3239)