【数轮】数论、质数、最大公约数、菲蜀定理

数学

唯一分解定理

n>=2都可以表示为质因数的乘方。
令 n = a1b1a2b2 … \dots
a1,b1 … \dots 都是质因数,b1,b2 … \dots 是对应质因数的数量。

下面是封装类:结果存放在vector m_a, m_n

class CUniqueFactorization
{
public:
	CUniqueFactorization(int iMax) {
		int iMaxSqrt = sqrt(iMax) + 2;
		m_vPrime = CreatePrime(iMaxSqrt);
	}
	void Factorization(int x) {
		m_a.clear();
		m_n.clear();
		for (const auto& iPre : m_vPrime) {
			int cnt = 0;
			while (0 == x % iPre) {
				cnt++;
				x /= iPre;
			}
			if (cnt > 0) {
				m_a.emplace_back(iPre);
				m_n.emplace_back(cnt);
			}
		}
		if (x > 1) {
			m_a.emplace_back(x);
			m_n.emplace_back(1);
		}
	}
	vector<int> m_a, m_n;
	vector<int> CreatePrimeOld(int iMax)
	{
		vector<int> vNo(iMax + 1);
		vector<int> vPrime;
		for (int i = 2; i <= iMax; i++)
		{
			if (!vNo[i])
			{
				vPrime.emplace_back(i);
			}
			for (const auto& n : vPrime)
			{
				if (n * i > iMax)
				{
					break;
				}
				vNo[n * i] = true;
			}
		}
		return vPrime;
	}
	vector<int> CreatePrime(int iMax)
	{
		vector<bool> isPrime(iMax + 1, true);
		vector<int> vPrime;
		for (int i = 2; i <= iMax; i++)
		{
			if (isPrime[i])
			{
				vPrime.emplace_back(i);
			}
			for (const auto& n : vPrime)
			{
				if (n * i > iMax) { break; }
				isPrime[n * i] = false;
				if (0 == i % n) { break; }
			}
		}
		return vPrime;
	}
	vector<int> m_vPrime;
};

调和级数

1+1/2 + 1/3 +1/4 ⋯ \cdots 1/ n 约等于 logn。
证明过程:
1/3 + 1/4 < (1/2) × \times × 2 = 1
1/5 + 1/6 + 1/7 + 1/8 < (1/4) × \times × 4 = 1
1/9+1/10+…1/16 < (1/8) × \times × 8 = 1
⋮ \vdots
1/2^(m-1)+ ⋯ \cdots + 1/2m < 1

区间公约数

n个数,那些数对非互质。两两枚举,时间复杂度是O(nn)。
令这些数最大值为m,枚举那些数是x$\in[2,m]的倍数,则时间复杂度是O(nlogn)。
一,相同值如果大于1,非互质。
二,如果同时x>1的倍数,非互质。
转化成并集查找计算连通区域,注意:两个连通区域合并,只需要从2个联通区域任取一点相连。

质数

质数分解

x的质因数中最多有一个大于 x \sqrt x x 。反证法:如果有两个质因数大于 x \sqrt x x ,则它们相乘大于 x × x \sqrt x \times \sqrt x x ×x ,和所有质因数相乘等于x矛盾。
小于等于x的质因数可以直接枚举。如何寻找大于 x \sqrt x x 的质因数?
x 如果包括小于等于 x \sqrt x x 的质因数x1,则x ÷ \div ÷=x1。直到不包括小于等于 x \sqrt x x 的质因数。如果此时x>1,则此时的x也是质因数。

for (int i = 0; i < nums.size(); i++) {
			int tmp = nums[i];
			for (auto& iPri : vPrime) {
				if (iPri * iPri > tmp) { break; }
				if (0 == tmp % iPri) { indexs[iPri].emplace_back(i); }
				while ((0 == tmp % iPri)) {
					tmp /= iPri;
				}
			}
			if( tmp > 1){ indexs[tmp].emplace_back(i); }
		}

埃氏筛

如何寻找[1,m]所有质数。从2其,如果i是质数,则将i的x倍(x>1)标记位非质数。时间复杂度:O(nlogn),logn是调和级数的和。

vector<int> CreatePrime(int iMax)
{
	vector<int> vNo(iMax + 1);
	vector<int> vPrime;
	for (int i = 2; i <= iMax; i++)
	{		
		if (!vNo[i])
		{
			vPrime.emplace_back(i);
		}
		for (const auto& n : vPrime)
		{
			if( n * i > iMax )
			{
				break;
			}
			vNo[n * i] = true;
		}		
	}
	return vPrime;
}

欧拉筛(线性筛)

埃氏筛枚举了所有a × \times ×b,其中a是质数,b是任意数。
欧拉筛增加了新条件:a <= b的最小质因数,也就a 是 a × \times ×b 的最小质因数。因为任意数的最小质因数都只有一个,故不会重复。故时间复杂度:O(n)
以12为例:
埃氏筛枚举了2次,2 × \times × 6 ,3 × \times × 4。
欧拉筛:只枚举了 2 × \times × 6 。4 枚举完2后,就结束了。
在这里插入图片描述

代码

vector<int> CreatePrime(int iMax)
{
	vector<bool> isPrime(iMax + 1,true);
	vector<int> vPrime;
	for (int i = 2; i <= iMax; i++)
	{
		if (isPrime[i])
		{
			vPrime.emplace_back(i);
		}
		for (const auto& n : vPrime)
		{
			if (n * i > iMax){break;}
			isPrime[n * i] = false;
			if (0 == i % n) { break; }
		}
	}
	return vPrime;
}

最大公约数

gcc,vc都有gcd函数,可以直接使用。

辗转相减法

求a,b的最大公约数。如果a,b相等,则a就是公约数。下面只讨论两者不等。
不失一般性,令a > b,其最大公约数为q。a = a1q,b=b1q ,令a - b =(a1-b1)q =c1q= c。则q也是(c,b)的公约数。
我们用反证法来证明c,b没有大于q的公约数。假定c,b有大于q的公约数q1,则a = (b2+c2)q2 ,b = b2q2。a,b也有公约数q2,和a,b的最大公约数是q矛盾。
不断持续此过程,可以保持公约数不变的情况下,让max(a,b)变小。由于a>b,故c >= q。经过有限回合,c一定变成q,b变成q后,a每次也减少q,直到a也变成q。

辗转相除法(欧几里得)求最大公约数

( a , b ) → 不失一般性,令 a > = b ( c = a m o d    b , d = b ) → 不失一般性,令 c > = d ( e = c m o d    d , f = d ) ⋯ (a,b)^{不失一般性,令a >= b}_\rightarrow (c= a \mod b,d= b) ^{不失一般性,令c >= d}_\rightarrow (e=c \mod d,f=d) \cdots (a,b)不失一般性,令a>=b(c=amodb,d=b)不失一般性,令c>=d(e=cmodd,f=d)
直到最后的两个数一个为0,则公约数是另外一个。比如:e为0,最大公约数就是f。f为0,最大公约数为e。
a,b不断变小,有限次数一定有一个数变为0。
令某两个数的最大公约数为q, 则这两个数可以表示为 q × a , q × b 则 q × ( a m o d    b ) , q × b 的最大公约数为 q 则这两个数可以表示为q \times a,q \times b 则 q \times (a \mod b) , q \times b 的最大公约数为q 则这两个数可以表示为q×a,q×bq×(amodb),q×b的最大公约数为q
a%b 为0,也符合数学定义: 0和任何数x的最大公约数是x。

二进制求公约数

求a,b的最大公约数。
一,如果a,b都是偶数,则GCD(a,b) = 2*GCD(a,b)。
二,如果a 是偶数,b是奇数(反之类似)。GCD(a,b)=GCD(a/2,b)。b是奇数,所以他们的公约数不包括2。
三,两者都是奇数。
3.1,两者相等。a就是最大公约数。
3.2,a b不等,不失一般性,令a>b。GCD(a,b) == GCD(a+b,b) == GCD((a+b)/2,b)
由于a,b是不断变小,一定会相等。

菲蜀定理

【数学归纳法 反证法】菲蜀定理

题解

质数判断、分解
【分解质因数 差分数组】2584. 分割数组使乘积互质
【状态机dp 状态压缩 分组】1994. 好子集的数目
【唯一分解定理 数学】1808好因子的最大数目
【单调栈】LeetCode:2818操作使得分最大
最大公约数
【栈 最小公倍数 最大公约数】2197. 替换数组中的非互质数
【最大公约数 排序】2344. 使数组可以被整除的最少删除次数
【二进制求公约数】【数学】【数论】2543. 判断一个点是否可以到达
【最大公约数】2862. 完全子集的最大元素和
区间最大公约数:调和级数o(nlogn)
【并集查找 最大公约数 调和数】952. 按公因数计算最大组件大小
【数论 最大公约数 调和数】【最大公约数】1819. 序列中不同最大公约数的数目
【最大公约数 调和级数】2183.统计可以被 K 整除的下标对数目
【调和级数 并集查找】1627. 带阈值的图连通性
【最大公约 调和奇数 并集查找】2709. 最大公约数遍历
菲蜀定理
【菲蜀定理 子序列】1250 检查「好数组」
唯一分解定理
【唯一分解定理】【动态规划】【前缀和】1735生成乘积数组的方案数
类似区间公约数
【动态规划】【前缀和】【分组】2338. 统计理想数组的数目
  • 75
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 50
    评论
《初等数论及其应用》是一本关于数论的教材,介绍了数论的基本概念、定理和证明方法,并探讨了数论在实际问题中的应用。 数论数学的一个分支,研究整数的性质和规律。《初等数论及其应用》首先介绍了整数、素数、最大公因数和最小公倍数等基本概念。然后讨论了素数的性质,包括素数的无穷性、素数分布的规律和素数定理等。接着介绍了数论中的重要定理,如费马小定理、欧拉定理和中国剩余定理等,以及它们的证明方法。此外,书中还包含了一些经典的数论问题和解法,如高斯平方和、尼科彻斯定理和无穷数列求和等。 除了介绍基本概念和定理外,该书还强调了数论在密码学、编码理论和计算机科学等领域中的应用。其中,密码学是数论的一个重要应用方向,通过利用数论中的一些难题和性质,可以设计出安全可靠的密码算法。此外,编码理论是应用数论研究信号编码和纠错编码的一门学科,数论中的一些技术和方法对编码理论的研究具有重要意义。计算机科学领域也广泛应用了数论中的一些概念和方法,如素数测试、大整数运算和随机数生成等。 总之,《初等数论及其应用》是一本系统介绍数论基本概念、定理和应用的教材。通过学习该书,读者可以了解数论的基础知识,掌握数论的基本方法和证明技巧,并了解数论在实际问题中的广泛应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 50
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闻缺陷则喜何志丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值