1. 程式人生 > >POJ 2417 Discrete Logging [BSGS演算法]

POJ 2417 Discrete Logging [BSGS演算法]

POJ 2417 Discrete Logging

Description

Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that BL == N (mod P)

Input Read several lines of input, each containing P,B,N separated by a space.

Output For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print “no solution”.

BSGS的裸題 給定A,B,p,求最小的非負整數x,滿足 A^x ≡ B(mod p) 令x=i*m-j,m=sqrt(p) A^(i*m-j)=B(mod p), A^j×B=A^(m*i) (mod p)。 列舉j(範圍0-m),將A^j×B存入hash表 列舉i(範圍1-m),從hash表中尋找第一個滿足A^j×B=A^(m*i) (mod C)。 此時x=i*m-j即為所求。

改了很久終於過了 - 一開始用了map不知道為什麼T了,後來改了Hash - sqrt(1.0*p)——不能用int - tot記得清零

#include<cstdio>
#include<cstring>
#include<cmath>
#define MOD 76543
using namespace std;
int p,tot;
int hs[MOD+1],id[MOD+1],next[MOD+1],head[MOD+1];
void insert(int x,int y)
{
    int k=x%MOD;
    hs[++tot]=x
;id[tot]=y;next[tot]=head[k];head[k]=tot; } int find(int x) { int k=x%MOD; for(int i=head[k];i;i=next[i]) if(hs[i]==x)return id[i]; return -1; } int BSGS(int a,int b,int p) { memset(head,0,sizeof(head)); if(b==1)return 0; tot=0; int m=sqrt(1.0*p),t=1,x=1; for(int i=0;i<m;i++,t=1LL*t*a%p)insert(1LL*t*b%p,i); for(long long i=m,j;i<p;i+=m) if((j=find(x=1LL*x*t%p))!=-1)return i-j; return -1; } int main() { int a,b; while(scanf("%d%d%d",&p,&a,&b)!=EOF) { int ans=BSGS(a,b,p); if(ans==-1)printf("no solution\n"); else printf("%d\n",ans); } return 0; }