HDU 2815 Mod Tree 解a^x = b(mod n)非互质
来源:互联网 发布:开淘宝网店怎么上货 编辑:程序博客网 时间:2024/04/30 18:55
题意:
求模方程 a^x = b(mod n)是否存在解x,如果存在,输出最小的x。
解题思路:
首先考虑简单的情况,求a^x = b(mod n),如果a,n互质,由欧拉定理 a^( phi(n) ) = 1 (mod n)可知,当x>phi(n)后a^x就开始循环了。所以只需要检查前phi(n)项是否有解,因为phi(n) <= n,为了方便,统一设定检查范围为0到n。然后我们先检查前m项 (令m = sqrt(n) ),保存所有a^i mod n的值 (0 <= i < m),接下来对于a^(m),a^(m+1)...a^(2m+1)就不用枚举来检查了,如果他们当中有解,则相当于存在a^i* a^m = b(mod n)。两边左乘a^(-m)得 a^i = ( b*a^(-m) ) (mod n),所以只需要判断有没有a^i = b*a^(-m) 。
如果a,n不互质的话,直接这样子做就不行了,既然我们有了a,n互质的做法,那就要想办法使得a,n互质。
所以每次都要把a,n的gcd约去,同时b也要约去gcd,如果b不能约去gcd说明无解。这样假设需要cnt个a和n约去才能使得a,n互质,这cnt个a约后得到的设为now,结果就是求now*a^x = b (mod n),也就转化成a,n互质的情况了,这样就很简单了~贴个代码 (ps:貌似好久没写博客了)
#include <stdio.h>#include <math.h>#include <map>using namespace std;#define LL __int64int exgcd(int a, int b, int &x, int &y) { if(!b) { x = 1; y = 0; return a; } int ret = exgcd(b, a%b, y, x); y -= a/b*x; return ret;}int gcd(int a, int b) { return b ? gcd(b, a%b) : a;}// 求逆元int inv(int a, int n) { int x, y; int d = exgcd(a, n, x, y); if(x < 0) x += n; return x;}int mul_mod(LL a, LL b, int n) { return a * b % n;}int pow_mod(int x, int n, int m) { int ret = 1; while(n) { if(n&1) ret = (LL)ret*x%m; x = (LL)x*x%m; n /= 2; } return ret;}//求解a^x = b (mod n) a, n互质int log_mod(int a, int b, int n) { int m = sqrt(n+0.5); int v = inv(pow_mod(a, m, n), n); map<int,int> x; x[1] = 0; int e = 1; for(int i = 1;i < m; i++) { e = mul_mod(e, a, n); if(!x.count(e)) x[e] = i; } for(int i = 0;i < m; i++) { if(x.count(b)) return i*m + x[b]; b = mul_mod(b, v, n); } return -1;}int solve(int a, int p, int b) { int cnt = 0; int now = 1; while(true) { // 结果已经等于b的情况 if(now%p == b) return cnt; int d = gcd(a, p); if(d == 1) { int v = inv(now, p); int ret = log_mod(a, (LL)b*v%p, p); if(ret == -1) return -1; return ret + cnt; } if(b % d) return -1; b /= d; p /= d; now = (LL)now*(a/d)%p; cnt++; }}int main() { int a, p, b; while(scanf("%d%d%d", &a, &p, &b) != -1) { if(b >= p) { puts("Orz,I can’t find D!"); continue; } int ans = solve(a, p, b); if(ans == -1) puts("Orz,I can’t find D!"); else printf("%d\n", ans); } return 0;}
- HDU 2815 Mod Tree 解a^x = b(mod n)非互质
- hdu 2815 Mod Tree 模方程a^x=b(mod n),n为任意正整数+模板题(扩展Baby Step Giant Step)
- hdu 3930 X^N=a(mod) p 求X
- a/b % Mod = a % (b * Mod) /b % Mod;
- 求解x=a^b(mod m)
- 求解x=a^b(mod m)
- HDU 2^x mod n = 1
- 求 X^a mod N
- 解一类x^a = b (mod p)的方程
- Poj 2417 Discrete Logging (Baby Step Giant Step 解 a^x = b (mod n) n为素数)
- (A^B mod C)|(a^(n!) mod c)
- Baby-step giant-step 解高次同余方程a^x=b(mod n) 模版
- 模取幂运算 计算a^b mod n
- HDU 1395 2^x mod n = 1
- hdu 1395 2^x mod n = 1
- HDU 1395 2^x mod n = 1
- hdu 1395-2^x mod n = 1-易超时
- HDU 1395 2^x mod n = 1 数论
- 第三章 目标文件里有什么
- 如何查看80端口是否被占用_端口被占用解决办法
- web.xml中welcome-file配置的问题
- 【开源工具】Cppcheck 1.54 C/C++静态代码分析工具
- 从零开始,学习windows编程(3)—hello.c的疑惑
- HDU 2815 Mod Tree 解a^x = b(mod n)非互质
- 从零开始,学习windows编程(4)--从libc.lib开始
- 从零开始,学习windows编程(5)--修改入口不为mainCRTStartup
- 从零开始,学习windows编程(6)--改换entry,link错误的简单分析
- 从零开始,学习windows编程外篇(1)--分析lib文件
- C程序小结3
- Hibernate双向1-N关联的简单示例
- iphone 重用机制
- 人不成熟的六大特征