POJ2417 Baby-Step-Gaint-Step 算法
来源:互联网 发布:链轮尺寸计算软件 编辑:程序博客网 时间:2024/06/05 00:47
考虑一个问题:A^x%p=B,给定A,B,p,求x的最小非负整数解。
在p是质数的情况下,这个问题比较简单。
A^x=B(mod P) (P is a Prime, A,B<P)Let m = floor(sqrt(P))Put A^0,A^1,...A^(m-1) into HashSet(You Can Also Use Map in STL),for Example M[A^i]=i.
if A^i=A^j(i<j), M[A^i=A^j]=i.
Enumerate i, Let x=i*m+j, A^(i*m)*A^j=B(mod C)Let E=A^(i*m),F=A^j,E*F=B(mod P) because (E,C)=1,(E,C)|B,we can use EXTgcd to get F.
If F is in the HashSet,then the minimum answer x=i*m+M[F].
Because P is a Prime, and A,B<P, then A^(P-1)=1(mod P). Then if a answer exists, the minimum answer must less then P.
So the range of i is [0,P/m].
If for all i we cannot find a answer, then no solution.
我亲手胡乱写的东西,能看懂才怪!再附上代码吧:(我的小数据范围是暴力的)
#include <cmath>#include <cstdio>#include <cctype>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;inline void Exgcd(LL a, LL b, LL &d, LL &x, LL &y) {if (!b) { d = a, x = 1, y = 0; }else { Exgcd(b, a % b, d, y, x), y -= x * (a / b); }}inline LL gcd(LL a, LL b) {return (!b) ? a : gcd(b, a % b);}inline LL Solve(LL a, LL b, LL c) { // ax=b(mod c)LL d, x, y;Exgcd(a, c, d, x, y);return (x + c) % c * b % c;}LL ksm(LL x, LL y, LL p) {LL res = 1, t = x;for(; y; y >>= 1) {if (y & 1) res = res * t % p;t = t * t % p;}return res;}const int mod = 13131;struct Hashset {int head[mod], next[40010], f[40010], v[40010], ind;void reset() {ind = 0;memset(head, -1, sizeof head);}void insert(int x, int _v) {int ins = x % mod;for(int j = head[ins]; j != -1; j = next[j])if (f[j] == x) {v[j] = min(v[j], _v);return;}f[ind] = x, v[ind] = _v;next[ind] = head[ins], head[ins] = ind++;}int operator [] (const int &x) const {int ins = x % mod;for(int j = head[ins]; j != -1; j = next[j])if (f[j] == x)return v[j];return -1;}}S;int main() {LL A, B, C;LL i;while(scanf("%I64d%I64d%I64d", &C, &A, &B) == 3) {if (C <= 100) {LL d = 1;bool find = 0;for(i = 0; i < C; ++i) {if (d == B) {find = 1;printf("%I64d\n", i);break;}d = d * A % C;}if (!find)puts("no solution");}else {int m = (int)sqrt(C);S.reset();LL d = 1;for(i = 0; i < m; ++i) {S.insert(d, i);d = d * A % C;}bool find = 0;int ins;for(i = 0; i * m < C; ++i) {LL t = Solve(ksm(A, i * m, C), B, C);if ((ins = S[t]) != -1) {printf("%I64d\n", i * m + ins);find = 1;break;}}if (!find)puts("no solution");}}return 0;}
0 0
- POJ2417 Baby-Step-Gaint-Step 算法
- Baby-Step-Gaint-Step算法详解
- poj2417(Discrete Logging)-Baby Step Giant Step
- POJ 2417 Discrete Logging Baby-Step-Gaint-Step
- poj2417 Discrete Logging(BSGS:Baby Step Giant Step)
- Baby step Giant step算法
- DAY09_baby step gaint step
- baby-step算法
- BSGS(baby step gaint step)+快速幂+exgcd逆元
- baby-step qiant-step
- Baby-step giant-step
- Baby-step giant-step
- baby step giant step
- Baby Step Giant Step
- Baby Step Giant Step
- Baby-Step Giant-Step
- 【POJ 3243-Clever Y】 与【POJ 2417-Discrete Logging】(解高次同余方程 Baby-Step-Gaint-Step)
- POJ 2417 Discrete Logging (Baby Step Giant Step算法)
- 安装Oracle JDK 7.0与8.0 for Mac OS X后Eclipse启动报错的解决之道
- Java log4j日志编写实例
- 编程中的细节
- makefile 文件的用法
- Qt连接mysql数据库程序发布问题
- POJ2417 Baby-Step-Gaint-Step 算法
- 第九周项目六—都要学C
- C#迁移winfrom项目出现CL.EXE -1问题的解决方案
- linux下maven2和maven3共存
- 通过WM_COPYDATA消息完成进程间通信
- dp与px转换
- 【例 2.10】
- hdu1716(库函数next_permutation)
- 项目六:穷举法解决组合问题(6)让计算机解决奥数题