POJ 2417 Discrete Logging [BSGS演算法]
阿新 • • 發佈:2018-12-10
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;
}