基础的数论知识
来源:互联网 发布:系统修复软件 编辑:程序博客网 时间:2024/05/22 16:01
素数定义
除了1和该数本身,不能被其他整数整除,1不是素数
素数判定
素数的判定没有统一的公式,可以通过枚举暴力方法判定,也可以基于费马定理和米勒-拉宾定理进行随机测试判定。
暴力判定
针对给定的正整数N,枚举1 to sqrt(N), 时间复杂度为O(sqrt(N)).
bool isPrime(long long N){ if(N == 1){ return false; } long long bound = sqrt(N); for(long long i = 2; i < bound; ++i){ if(N % i == 0){ return false; } } return true;}
随机测试判定
给定一个素数p,满足费马定理或米勒-拉宾定理:
费马定理
a^p mod p = a
米勒-拉宾定理
a^(p-1) mod p = 1
因为这两个定理都是p为素数的必要不充分条件,但若对于整数p,费马定理和米勒-拉宾定理成立,有很大的概率判断p为素数,因此可以随机产生整数a,多次进行测试,如果不满足则p为合数,如果都满足,则很有可能为素数。下面编程实现a^b mod n:
long long pow_mod(long long a, long long b, long long n){ if(!b){ return 1; } long long ans = pow_mod(a, b / 2, n); ans = ans * ans % n; if(b % 2 == 1){ ans = ans * a % n; } return ans;}
素数筛选
所有的素数能不能由一个统一的公式产生,这一直是无数先哲试图解决的一个问题,迄今为止,仍然没有找到这样的一个万能公式,因此只能通过暴力筛选素数。
const int maxn = 10001;const int maxp = 1000;int vis[maxn]; //vis[i] = 1, 则i是和数; vis[i] = 0,则i是1或者素数int prime[maxp]; //从小到大保存maxn内所有素数//生成素数表,放在prime中,返回素数个数int get_primes(){ //标记素数和合数 int m = sqrt(maxn); for(int i = 2; i <= m; ++i){ if(!vis[i]){ for(int j = i * i; j <= maxn; j += i){ vis[j] = 1; } } } //存储素数 int count = 0; for(int p = 2; p <= maxn; ++p){ if(!vis[p]){ prime[count++] = p; } } return count;}
分解素因子
分解整数
通常使用试除法,首先构造一个素数表,然后扫描素数表,整除则加入解集。
N!中素因子p的个数
Leetcode中有一道有N!结果里,结尾0的个数的题目:Factorial Trailing Zeroes,本质就是求素因子5的个数
int Num_p(int N, p){ int num = 0; while(N){ num += N / p; N /= p; } return num;}
最大公约数(GCD)
求解两个数的最大公约数和最小公倍数是一个常见的问题,其中最小公倍数需要求最大公约数,因此重要的是求两个数的最大公约数。常见的方法是欧几里得算法和扩展欧几里得算法;
欧几里得算法
定理:gcd(a, b) = gcd(b, a mod b)
证明:设a = kb + r; p = gcd(a, b); b = mp; a = np; 则 a = kmp + r = np, r = (n-km)p, 故 p 也是r的约数,得证。代码如下:
int gcd(int a, int b){ if(!b){ return a; } return gcd(b, a % b);}
扩展欧几里得算法
对于不完全为0的非负整数a, b;必然存在整数对x, y, 使得(a,b) = ax + by,其中(a,b)= gcd(a, b);下面编程实现扩展欧几里得:
int 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 = y - a / b * x; return ret;}x,y的迭代更新公式可以容易使用递推归纳证明。这里需要指出的是,这里得到的满足(a,b)= ax + by的整数对x,y并不是唯一的,只是abs(x) + abs(y)取最小值。
求解模线性方程 ax = b(mod n)
解模线性方程相当与求 ax = b + kn => ax + n(-k) = b, 这有点类似用扩展欧几里得算法求(a,b)= ax + by.若(a, n)是 b的约数,即可以求解模线性方程有解。现在我们好奇的是如果已知其中一个解x(可以通过扩展欧几里得算法求得),能否求得其他解。
事实上,如果 ax = b(mod n), 则(x + k * n / (a, n))mod n 也必为解。
贴一道有意思的题目
1/n = 1/a + 1/b; (0<a<=b), 给定整数n,求出所有满足要求的的整数对a,b;若没有,则返回空集。
这道题目稍微化简就很明朗了:1/n = 1/(n+k) + k/n(n+k) => 1/n = 1/(n+k) + 1/(n^2/k + n), 所有k只要满足为n^2的因子就够了。
0 0
- 基础的数论知识
- 一些基础的数论知识
- 基础数论知识总结
- 简单的数论小知识
- 数论知识
- 【知识】 数论
- 数论知识
- 数论知识
- 数论知识
- 数论基础的补充讲解
- NYoj 416 数论的一个小知识
- 与密码学有关的数论知识
- 康复计划#2 常用基础数论知识杂烩
- 康复计划#2 常用基础数论知识杂烩
- 康复计划#2 常用基础数论知识杂烩
- 康复计划#2 常用基础数论知识杂烩
- 水水数论1:基础的基础
- 数论基础(浅谈数论的部分实现)
- unity3d 4.6RectTransform 的一些设置
- 触发器判断更改的行或列
- android内置浏览器不支持websocket的解决方法
- Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单
- -boundingRectWithSize:options:attributes:context:用法
- 基础的数论知识
- perl 多线程及信号控制
- 解析apache的httpd.conf配置内容
- Andoird 监听开机广播和关机广播
- 为接下来的3年而奋斗
- 建立本类特有的判断对象是否相同的依据
- java CyclicBarrier
- iOS App Icons for iOS 8
- mysql查询今天,昨天,近7天,近30天,本月,上一月数据的方法