【poj2417】 Discrete Logging

http://poj.org/problem?id=2417 (题目链接)

题意

  求解$${A^X≡B~(mod~P)}$$

Solution

  BSGS。

细节

  map TLE飞,只好写了hash挂链。。从TLE到110MS→_→

代码

// poj2417
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf (1ll<<29)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;

const int M=1000007;
struct Hash {int w,id,next;}h[1000010];
int head[M],cnt;

void insert(LL x,int I) {
	int id=x%M;
	h[++cnt]=(Hash){x,I,head[id]};head[id]=cnt;
}
int find(LL x) {
	int id=x%M;
	if (!head[id]) return -1;
	for (int i=head[id];i;i=h[i].next) if (h[i].w==x) return h[i].id;
	return -1;
}
LL power(LL a,LL b,LL p) {
	LL res=1;
	while (b) {
		if (b&1) (res*=a)%=p;
		b>>=1;(a*=a)%=p;
	}
	return res;
}
LL BSGS(LL a,LL b,LL p) {
	int m=sqrt(p);
	memset(head,0,sizeof(head));
	insert(1,0);
	LL inv=power(a,p-1-m,p),e=1;
	for (int i=1;i<=m;i++) {
		e=e*a%p;
		if (find(e)==-1) insert(e,i);
	}
	for (int i=0;i*m<p;i++) {
		int x=find(b);
		if (x!=-1) return x+i*m;
		b=b*inv%p;
	}
	return -1;
}
int main() {
	LL p,a,b;
	while (scanf("%lld%lld%lld",&p,&a,&b)!=EOF) {
		LL ans=BSGS(a,b,p);
		if (ans==-1) puts("no solution");
		else printf("%lld\n",ans);
	}
    return 0;
}

 

posted @ 2016-12-20 21:03  MashiroSky  阅读(...)  评论(...编辑  收藏