POJ 2417 Discrete Logging
2016-07-12 22:25
393 查看
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)
【题目分析】
同余方程组的题目。属于离散对数的范畴。但是这类题目并没有多项式的算法(那密码学还学什么呢)。所以只能枚举,(B^m)^i这样的枚举方式,可以尽量的减少搜索量。
【代码】
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)
【题目分析】
同余方程组的题目。属于离散对数的范畴。但是这类题目并没有多项式的算法(那密码学还学什么呢)。所以只能枚举,(B^m)^i这样的枚举方式,可以尽量的减少搜索量。
【代码】
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> const int maxn=1000001; using namespace std; bool hash[maxn]; long long p[maxn],var[maxn]; inline void ins(long long n,long long v) { int x=v%maxn; while (hash[x]&&var[x]!=v){x++;if(x==maxn)x=0;} if (!hash[x]) var[x]=v,hash[x]=true,p[x]=n; } long long find(long long v) { int x=v%maxn; while (hash[x]&&var[x]!=v) {x++;if (x==maxn) x=0;} if (hash[x]==false) return -1; return p[x]; } long long exgcd(long long a,long long b,long long &x,long long &y) { if (!b) {x=1,y=0;return a;} long long r=exgcd(b,a%b,x,y),t=x; x=y; y=t-a/b*y; return r; } long long bsgs(long long a,long long b,long long p) { long long num=1; int m=ceil(sqrt(p*1.0)); for (int i=0;i<m;++i) ins(i,num),num=num*a%p; long long ret=1; for (int i=0;i<m;++i) { long long x,y,r=exgcd(ret,p,x,y); x=x*b;x=(x%(p/r)+(p/r))%(p/r); long long ans=find(x); if (ans!=-1) return (ans+i*m); ret=ret*num%p; } return -1; } int main() { long long n,b,P; while (scanf("%lld%lld%lld",&P,&b,&n)!=EOF) { memset(hash,0,sizeof hash); memset(var,-1,sizeof var); memset(p,-1,sizeof p); long long ans=bsgs(b,n,P); if (ans==-1) printf("no solution\n"); else printf("%lld\n",ans); } }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题