【bzoj2480】Mod 扩展大步小步
2015-10-09 08:38
190 查看
http://blog.miskcoo.com/2015/05/discrete-logarithm-problem
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <map> #define Rep(i, x, y) for (int i = x; i <= y; i ++) #define Dwn(i, x, y) for (int i = x; i >= y; i --) #define RepE(i, x) for(int i = pos[x]; i; i = g[i].nex) using namespace std; typedef long long LL; map<LL, int> m1; int a, b, p, ans; int Pow(LL x, int y, int m) { LL z = 1; while (y) { if (y & 1) (z *= x) %= m; y >>= 1, (x *= x) %= m; } return z; } LL gcd(LL x, LL y) { return !y ? x : gcd(y, x % y); } int Baby_step_gaint_step() { a %= p, b %= p, m1.clear(); int k0 = 0; LL t = 1, k; while ((k = gcd(a, p)) > 1) { if (b % k != 0) return -1; p /= k, b /= k, t = (t * a / k) % p; k0 ++; if (b == t) return k0; } int u = sqrt(p) + 1; LL x = 1, z, num, z0; Rep(i, 1, u) { LL p1 = x * b % p; m1[p1] = i, x = a * x % p; } z = x * t % p, z0 = x, num = u; Rep(i, 1, u) { if (m1[z]) return num - m1[z] + k0 + 1; z = z * z0 % p, num += u; } return -1; } int main() { while (scanf ("%d%d%d", &a, &p, &b) != EOF) { if (!a && !b && !p) break ; ans = 0; LL x = 1; while (x != b && ans <= 32) x = x * a % p, ans ++; if (x != b) ans = Baby_step_gaint_step(); if (ans == -1) puts("No Solution"); else printf("%d\n", ans); } return 0; }
相关文章推荐
- 将秒转换成时分秒
- 第6周 项目2-建立链栈算法库
- Developer Productivity: Skilled Versus Average
- 第4周项目3-单链表的运用(2)
- 第六周项目1--建立顺序栈算法库
- How to Spot a Good IT Developer
- 星级设置
- 前端开发,在工具配置时可能出现的问题
- 【第6周 项目2 - 建立链栈算法库】
- 第四周项目1建立单链表
- 第四周项目三-单链表的应用(2)
- 第6周 项目2-建立链栈算法库
- 如何在一台电脑上开启多个tomcat
- 第四周项目1--建立单链表
- 项目范围管理的重点
- 第四周项目3--单链表应用之逆置
- 如果没有 Android,世界会怎样?
- 第四周项目三 单链表的应用(2)
- 第3周项目1 顺序表的基本运算(3)
- TestSSLServer