poj 3243 poj 2417 hdu 2815(解高次同余方程的应用)
来源:互联网 发布:js处理遍历json数据 编辑:程序博客网 时间:2024/04/29 01:26
高次同余方程用babystep_giantstep算法来解,具体原理学不懂,学会了怎么用。
poj 3243:
题意:
已知x,z,k,求同余方程 x ^ y mod z = k 中的y值。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = 4 * atan(1.0);const double ee = exp(1.0);const int HASH = 65536;struct hashMap{ int head[HASH], Size; int next[HASH]; LL state[HASH], val[HASH]; void init() { memset(head, -1, sizeof(head)); Size = 0; } void Insert(LL st, LL sv) { LL h = st % HASH; for (int p = head[h]; p != -1; p = next[p]) if (state[p] == st) return; state[Size] = st; val[Size] = sv; next[Size] = head[h]; head[h] = Size++; } LL Find(LL st) { LL h = st % HASH; for (int p = head[h]; p != -1; p = next[p]) if (state[p] == st) return val[p]; return -1; }} hashmap;LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a % b);}void exgcd(LL a, LL b, LL& d, LL& x, LL& y){ if (b == 0) { d = a; x = 1; y = 0; } else { exgcd(b, a % b, d, y, x); y -= a / b * x; }}LL inv(LL a, LL n){ LL x, y, d; exgcd(a, n, d, x, y); return (x + n) % n;}LL pow_mod(LL a, LL n, LL mod){ if (n == 0) return 1; LL x = pow_mod(a, n >> 1, mod); LL res = x * x % mod; if (n % 2) res = a * res % mod; return res;}LL babystep_giantstep(LL a, LL b, LL n){ for (LL i = 0, e = 1; i <= 100; i++) { if (e == b) return i; e = (e * a) % n; } LL k = 1, cnt = 0; while (1) { LL t = gcd(a, n); if (t == 1) break; if (b % t != 0) return -1; n /= t; b /= t; k = (k * a / t) % n; cnt++; } hashmap.init(); hashmap.Insert(1, 0); LL e = 1, m = (LL)(sqrt(n + 0.5)); for (int i = 1; i <= m; i++) { e = (e * a) % n; hashmap.Insert(e, i); } LL p = inv(pow_mod(a, m, n), n), v = inv(k, n); for (int i = 0; i <= m; i++) { LL t = hashmap.Find((b * v) % n); if (t != -1) return i * m + t + cnt; v = (v * p) % n; } return -1;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL LL x, z, k; while (scanf("%lld%lld%lld", &x, &z, &k) == 3) { if (!x && !z && !k) break; LL ans = babystep_giantstep(x % z, k % z, z); if (ans == -1) printf("No Solution\n"); else printf("%lld\n", ans); } return 0;}
poj 2417:
同理;
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = 4 * atan(1.0);const double ee = exp(1.0);const int HASH = 65536;struct hashMap{ int head[HASH], Size; int next[HASH]; LL state[HASH], val[HASH]; void init() { memset(head, -1, sizeof(head)); Size = 0; } void Insert(LL st, LL sv) { LL h = st % HASH; for (int p = head[h]; p != -1; p = next[p]) if (state[p] == st) return; state[Size] = st; val[Size] = sv; next[Size] = head[h]; head[h] = Size++; } LL Find(LL st) { LL h = st % HASH; for (int p = head[h]; p != -1; p = next[p]) if (state[p] == st) return val[p]; return -1; }} hashmap;LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a % b);}void exgcd(LL a, LL b, LL& d, LL& x, LL& y){ if (b == 0) { d = a; x = 1; y = 0; } else { exgcd(b, a % b, d, y, x); y -= a / b * x; }}LL inv(LL a, LL n){ LL x, y, d; exgcd(a, n, d, x, y); return (x + n) % n;}LL pow_mod(LL a, LL n, LL mod){ if (n == 0) return 1; LL x = pow_mod(a, n >> 1, mod); LL res = x * x % mod; if (n % 2) res = a * res % mod; return res;}LL babystep_giantstep(LL a, LL b, LL n){ for (LL i = 0, e = 1; i <= 100; i++) { if (e == b) return i; e = (e * a) % n; } LL k = 1, cnt = 0; while (1) { LL t = gcd(a, n); if (t == 1) break; if (b % t != 0) return -1; n /= t; b /= t; k = (k * a / t) % n; cnt++; } hashmap.init(); hashmap.Insert(1, 0); LL e = 1, m = (LL)(sqrt(n + 0.5)); for (int i = 1; i <= m; i++) { e = (e * a) % n; hashmap.Insert(e, i); } LL p = inv(pow_mod(a, m, n), n), v = inv(k, n); for (int i = 0; i <= m; i++) { LL t = hashmap.Find((b * v) % n); if (t != -1) return i * m + t + cnt; v = (v * p) % n; } return -1;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL LL p, b, n; while (scanf("%lld%lld%lld", &p, &b, &n) == 3) { LL ans = babystep_giantstep(b % p, n % p, p); if (ans == -1) printf("no solution\n"); else printf("%lld\n", ans); } return 0;}
hdu 2815:
题意:
给一棵树,每个节点有k个儿子,求这棵树的最小深度d,使得这个深度的节点数对p取模的结果为n。
解析:
一棵满树深度为d时的节点数为 k ^ d 。
所以题目转化为 k ^ d mod p = n.
另外,如果n > p,显然无解。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = 4 * atan(1.0);const double ee = exp(1.0);const int HASH = 65536;struct hashMap{ int head[HASH], Size; int next[HASH]; LL state[HASH], val[HASH]; void init() { memset(head, -1, sizeof(head)); Size = 0; } void Insert(LL st, LL sv) { LL h = st % HASH; for (int p = head[h]; p != -1; p = next[p]) if (state[p] == st) return; state[Size] = st; val[Size] = sv; next[Size] = head[h]; head[h] = Size++; } LL Find(LL st) { LL h = st % HASH; for (int p = head[h]; p != -1; p = next[p]) if (state[p] == st) return val[p]; return -1; }} hashmap;LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a % b);}void exgcd(LL a, LL b, LL& d, LL& x, LL& y){ if (b == 0) { d = a; x = 1; y = 0; } else { exgcd(b, a % b, d, y, x); y -= a / b * x; }}LL inv(LL a, LL n){ LL x, y, d; exgcd(a, n, d, x, y); return (x + n) % n;}LL pow_mod(LL a, LL n, LL mod){ if (n == 0) return 1; LL x = pow_mod(a, n >> 1, mod); LL res = x * x % mod; if (n % 2) res = a * res % mod; return res;}LL babystep_giantstep(LL a, LL b, LL n){ for (LL i = 0, e = 1; i <= 100; i++) { if (e == b) return i; e = (e * a) % n; } LL k = 1, cnt = 0; while (1) { LL t = gcd(a, n); if (t == 1) break; if (b % t != 0) return -1; n /= t; b /= t; k = (k * a / t) % n; cnt++; } hashmap.init(); hashmap.Insert(1, 0); LL e = 1, m = (LL)(sqrt(n + 0.5)); for (int i = 1; i <= m; i++) { e = (e * a) % n; hashmap.Insert(e, i); } LL p = inv(pow_mod(a, m, n), n), v = inv(k, n); for (int i = 0; i <= m; i++) { LL t = hashmap.Find((b * v) % n); if (t != -1) return i * m + t + cnt; v = (v * p) % n; } return -1;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL LL k, p, n; while (scanf("%I64d%I64d%I64d", &k, &p, &n) == 3) { if (p < n) printf("Orz,I can’t find D!\n"); else { LL ans = babystep_giantstep(k % p, n % p, p); if (ans == -1) printf("Orz,I can’t find D!\n"); else printf("%I64d\n", ans); } } return 0;}
0 0
- poj 3243 poj 2417 hdu 2815(解高次同余方程的应用)
- 高次同余方程:poj 3243+poj 2417+hdu 2815 (Baby Step Giant Step 算法)
- poj 1061(线性同余方程。。。。)
- POJ 2115(线性同余方程)
- POJ 3243 Clever Y 解高次同余方程
- POJ 2417 Discrete Logging(解高次同余方程)
- 【POJ 3243-Clever Y】 与【POJ 2417-Discrete Logging】(解高次同余方程 Baby-Step-Gaint-Step)
- poj 2115 同余方程
- poj 2891 同余方程
- POJ 2115 同余方程
- POJ 1061 同余方程
- 解高次同余方程的应用
- POJ 2417 && POJ 3243 求解高次同余方程 BSGS
- POJ 2142 && HDU 1356 The Balance(一元线性同余方程)
- poj 1061 青蛙的约会 (解同余方程)
- POJ 1061 青蛙的约会 同余方程
- POJ 1061 青蛙的约会 一元线性同余方程
- POJ 3243 离散对数-高次同余方程求解
- 2015
- 01 复杂系统结构
- PBOC/EMV之电子现金应用
- W3School 教程整理
- web framework 评估标准和评估方法 -- web框架哪家强?
- poj 3243 poj 2417 hdu 2815(解高次同余方程的应用)
- webpack- the next requireJS
- POI获取单元格值
- mysql 创建用户并分配权限
- win下安装JDK并且配置环境变量
- Oracle是否根据ROWID顺序读取记录|oracle sql方面
- 新一年开始
- WordPress企业建站心得
- Write Css Codes Distinct From Different Pages