您的位置:首页 > 其它

POJ 2417 Discrete Logging 离散对数/BabyStep_GiantStep

2012-03-14 22:36 411 查看
题意:BL == N (mod P),并且p是素数

题解:

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

#define lint  __int64
#define MAXN 131071
struct HashNode { lint data, id, next; };
HashNode hash[MAXN<<1];
bool flag[MAXN<<1];
lint top;

lint gcd ( lint a, lint b )
{
return b ? gcd ( b, a % b ) : a;
}

lint ext_gcd ( lint a, lint b, lint& x, lint& y )
{
lint t, ret;
if ( b == 0 )
{
x = 1, y = 0;
return a;
}
ret = ext_gcd ( b, a % b, x, y );
t = x; x = y; y = t - a / b * y;
return ret;
}

lint mod_exp ( lint a, lint b, lint n )
{
lint ret = 1;
a = a % n;
while ( b >= 1 )
{
if ( b & 1 )
ret = ret * a % n;
a = a * a % n;
b >>= 1;
}
return ret;
}

void Insert ( lint index, lint num )
{
lint k = num % MAXN;
if ( flag[k] == false )
{
flag[k] = true;
hash[k].id = index;
hash[k].data = num;
hash[k].next = -1;
return;
}
while ( hash[k].next != -1 )
{
if ( hash[k].data == num ) return;
k = hash[k].next;
}
if ( hash[k].data == num ) return;
hash[k].next = ++top;
hash[top].id = index;
hash[top].data = num;
hash[top].next = -1;
}

lint Find ( lint num )
{
lint k = num % MAXN;
if ( flag[k] == false ) return -1;
while ( k != -1 )
{
if ( hash[k].data == num )
return hash[k].id;
k = hash[k].next;
}
return -1;
}

lint BabyStep_GiantStep ( lint A, lint B, lint C )
{
top = MAXN; B %= C;
lint tmp, i, x, y, D;
lint M = (lint)(ceil(sqrt(C+0.0)));
lint K = mod_exp ( A, M, C );
for ( tmp = 1, i = 0; i <= M; tmp = tmp * A % C, i++ )
Insert ( i, tmp );

for ( D = 1, i = 0; i <= M; i++ )
{
ext_gcd ( D, C, x, y );
tmp = ((x * B) % C + C) % C;
if ( (y = Find(tmp)) != -1 )
return i * M + y;
D = D * K % C;
}
return -1;
}

int main()
{
lint P, B, N;
while (scanf("%I64d%I64d%I64d",&P,&B,&N)!=EOF )
{
memset(flag,0,sizeof(flag));
lint ret = BabyStep_GiantStep (B,N,P);
if ( ret == -1 ) printf("no solution\n");
else printf("%I64d\n",ret);
}
return 0;
}


下面是HDU 2815 的代码:

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

//BabyStep_GiantStep解决离散对数问题
#define lint __int64
#define MAXN 131071
struct HashNode { lint data, id, next; };
HashNode hash[MAXN<<1];
bool flag[MAXN<<1]; //flag[i] == 0,表示位置i没有放入元素
lint top; //用于解决冲突

void Insert ( lint a, lint b )
{
lint k = b & MAXN;
if ( flag[k] == false )
{
flag[k] = true;
hash[k].next = -1;
hash[k].id = a;
hash[k].data = b;
return;
}
while( hash[k].next != -1 )
{
if( hash[k].data == b ) return;
k = hash[k].next;
}
if ( hash[k].data == b ) return;
hash[k].next = ++top;
hash[top].next = -1;
hash[top].id = a;
hash[top].data = b;
}

lint Find ( lint b )
{
lint k = b & MAXN;
if( flag[k] == false ) return -1;
while ( k != -1 )
{
if( hash[k].data == b ) return hash[k].id;
k = hash[k].next;
}
return -1;
}

lint gcd ( lint a, lint b )
{
return b ? gcd ( b, a % b ) : a;
}

lint ext_gcd (lint a, lint b, lint& x, lint& y )
{
lint t, ret;
if ( b == 0 )
{
x = 1, y = 0;
return a;
}
ret = ext_gcd ( b, a % b, x, y );
t = x, x = y, y = t - a / b * y;
return ret;
}

lint mod_exp ( lint a, lint b, lint n )
{
lint ret = 1;
a = a % n;
while ( b >= 1 )
{
if( b & 1 )
ret = ret * a % n;
a = a * a % n;
b >>= 1;
}
return ret;
}

lint BabyStep_GiantStep ( lint A, lint B, lint C )
{
top = MAXN;  B %= C;
lint tmp = 1, i;
for ( i = 0; i <= 100; tmp = tmp * A % C, i++ )
if ( tmp == B % C ) return i;

lint D = 1, cnt = 0;
while( (tmp = gcd(A,C)) !=1 )
{
if( B % tmp ) return -1;
C /= tmp;
B /= tmp;
D = D * A / tmp % C;
cnt++;
}

lint M = (lint)ceil(sqrt(C+0.0));
for ( tmp = 1, i = 0; i <= M; tmp = tmp * A % C, i++ )
Insert ( i, tmp );

lint x, y, K = mod_exp( A, M, C );
for ( i = 0; i <= M; i++ )
{
ext_gcd ( D, C, x, y ); // D * X = 1 ( mod C )
tmp = ((B * x) % C + C) % C;
if( (y = Find(tmp)) != -1 )
return i * M + y + cnt;
D = D * K % C;
}
return -1;
}

int main()
{
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF)
{
if(B>=C){puts("Orz,I can’t find D!");continue;}
memset(flag,0,sizeof(flag));
int tmp=BabyStep_GiantStep(A,B,C);
if(tmp<0)puts("Orz,I can’t find D!");
else printf("%d\n",tmp);
}
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: