POJ 2417 Discrete Logging 离散对数/BabyStep_GiantStep
来源:互联网 发布:淘宝上如何用微信支付 编辑:程序博客网 时间:2024/05/11 22:44
题意:BL == N (mod P),并且p是素数
题解:
#include<cstdio>#include<cmath>#include<cstring>using namespace std;#define lint __int64#define MAXN 131071struct 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 131071struct 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;}
- POJ 2417 Discrete Logging 离散对数/BabyStep_GiantStep
- POJ 2417 Discrete Logging 离散对数
- poj 2417 Discrete Logging(求离散对数)
- POJ 2417 Discrete Logging(离散对数 BSGS)
- POJ-2417 Discrete Logging (BSGS算法,离散对数)
- 【哈希表除留余数法+BSGS算法求离散对数】POJ Discrete Logging 2417
- poj2417 Discrete Logging (计算离散对数)
- Discrete Logging[POJ 2417]
- POJ 2417 Discrete Logging
- POJ 2417 Discrete Logging
- poj 2417 Discrete Logging
- POJ 2417 Discrete Logging BSGS
- [POJ 2417]Discrete Logging:BSGS
- POJ 2417 Discrete Logging 笔记
- POJ 2417 离散对数
- POJ 2417 Discrete Logging (baby_step,giant_step算法)
- [poj 2417]Discrete Logging 数论 BSGS
- [poj 2417] Discrete Logging · BSGS
- C中的预编译
- 对/etc/rc.d/init.d目录的一点理解
- 一致性hash算法 - consistent hashing
- C# 创建 使用 本地数据库
- 初学android 几点小常识
- POJ 2417 Discrete Logging 离散对数/BabyStep_GiantStep
- DefaultHttpClient进行BasicAuth重复请求的问题(转)
- ContentProvider和Uri详解
- Android学习笔记(15)————android工程中新建Class注意事项
- zoj3583 Simple Path
- 第四周任务一
- Struts2 学习笔记——异常机制
- 《新日语基础教程》学习笔记——第五课
- 用 autoconf 和 automake 自动生成 Makefile