首页 > 其他分享 >基础数论 质数与约数

基础数论 质数与约数

时间:2024-07-26 19:40:19浏览次数:14  
标签:约数 frac gcd 数论 质数 times int

基础数论

前置芝士:

等比数列求和: \(S_n=a_0\frac{1-q^n}{1-q}\)

质数与约数:

 

整除与约数

设 \(n\) 为非负整数,\(d\) 为正整数,若 \(\frac{n}{d}\) 为整数,则称 \(d\) 整除 \(n\),记为\(d\mid n\)。此时,则称 \(d\) 是 \(n\) 的约数,或因数、因子;称 \(n\) 为 \(d\) 的倍数。

 

质数与合数的定义:

对于 \(n \geq 2\) ,若 \(\forall 1<i<n,i\nmid n\) ,则称 \(n\) 为质数,否则 \(n\)​ 为合数。

 

质数判定:

试除法:

单次时间复杂度 \(O(\sqrt n\ )\)

代码
bool is_prime(int n) {
	if(n < 2)
		return false;
	for(int i=2; i<= sqrt(n); ++i) {
		if(n % i == 0)
			return false;
	}
	return true;
}

 

质数筛法一:

从 \(2\) 到 \(n\) 枚举整数 \(i\),标记大于 \(i\) 且不大于 \(n\) 的 \(i\) 的倍数。枚举到 \(i\) 时,若 \(i\) 没有被标记过,则 \(i\) 为质数。

时间复杂度 \(O(\sum_{i=1}^n \frac{n}{i})=O(n\log n)\)

代码
void found_prime() {
	memset(vis, 0, sizeof(vis));
	vis[0] = 1; vis[1] = 1; // 特殊处理 0 和 1
	for(int i=2; i<=n; ++i) {
		for(int j=i*2; j<=n; j+=i)
			vis[j] = 1; // 标记合数
    }
}

 

埃氏筛:

只需要枚举质数的倍数就可以标记到所有合数了。实际上对于每个质数 \(p\) 而言,小于\(p^2\) 的 \(p\) 的倍数在扫描到更小的质数时就已经被标记过了。

从 \(2\) 到 \(n\) 枚举整数 \(i\),若 \(i\) 是质数,则把 \(i^2\) , \((i+1) \times i\), \(\cdots\), \(\lfloor \frac{n}{i}\rfloor \times i\) 标记为合数。枚举到 \(i\) 时,若 \(i\) 没有被标记过,则 \(i\) 为质数。

时间复杂度 \(O(\sum_{pr[i]\leq n}\frac{n}{pr[i]})=O(n\log\log n)\)

代码
void found_prime() {
	memset(vis, 0, sizeof(vis));
	vis[0] = 1; vis[1] = 1; // 特殊处理 0 和 1
	for(int i=2; i<=n; ++i) {
		if(!vis[i]) { // i 为质数
			for(int j=i*i; j<=n; j+=i)
				vis[j] = 1; // 标记合数
		}
	}
}

 

线性筛:

用每一个合数的最小质因子来标记这个合数。时间复杂度 \(O(n)\)

代码
int pr[N],cnt;
bool vis[N];
void init(){
	int n=1e5+50;
	for(int i=2;i<=n;i++){
		if(!vis[i]){pr[++cnt]=i;}
		for(int j=1;j<=cnt&&i*pr[j]<=n;j++){
			vis[i*pr[j]]=1;
			if(i%pr[j]==0)break;
		} 
	}
}

 

区间筛:(埃氏筛)

代码
const int maxn = 1e6+10;
typedef long long LL;
bool is_prime[maxn];  //标记a~b范围内的质数 
bool is_prime_small[maxn];  //标记 1~sqrt(n)范围内的所有质数 
LL a, b;

//对区间[a, b]内的整数执行筛法,is_prime[i-a]=true表示i是素数 
void found_prime()
{
	for(LL i=0; i*i<=b; ++i)
		is_prime_small[i] = true; 
	is_prime_small[1] = false;
	for(LL i=0; i<=b-a; ++i)
		is_prime[i] = true;
		
	for(LL i=2; i*i<=b; ++i) {
		if(is_prime_small[i]) {  // i是质数 
			for(LL j=i*i; j*j<=b; j+=i)  // 标记 sqrt(b) 以内的i的倍数 
				is_prime_small[j] = false;
			for(LL j = max(2LL, (a+i-1)/i) * i; j<=b; j+=i)  //标记[a, b]中i的倍数 
				is_prime[j-a] = false;
		}
	}	
}

 

算术基本定理:

任何一个大于 1 的正整数都能唯一分解为若干个质数的乘积。

设 \(n\geq2\) 为整数,有唯一的分解式:

\[n=p_1^{c_1}\times p_2^{c_2}\times \cdots\times p_m^{c_m}=\prod_{i=1}^mp_i^{c_i} \]

其中 \(c_i\) 都是正整数,\(p_i\) 都是质数,且满足 \(p_1\leq p_2\leq...\leq p_m\)

根据算术基本的定理,对于任意一个大于 \(2\) 的整数 \(n\),他的正约数集合可以写作:

\[\{p_1^{b_1}\times p_2^{b_2}\times \cdots\times p_m^{b_m}\} (0\leq b_i\leq c_i) \]

推论一: \(n\) 的正约数个数为:

\[(c_1+1)\times (c_2+1)\times \cdots\times (c_m+1)=\prod_{i=1}^m(c_i+1) \]

推论二: \(n\) 的所有正约数之和为:

\[(1+p_1+p_1^2+...+p_1^{c_1})\times\cdots\times (1+p_m+p_m^2+...+p_m^{c_m})=\prod_{i=1}^m\sum_{j=0}^{c_i}p_i^j \]

 

阶乘分解

对于一个数 \(n\) 求 \(n!\) 的质因数分解:

考虑对于一个质数 \(p_i\) 求 \(n!\) 中包含多少个 \(p_i\)
答案是 \(\sum_{i=1}^{\lfloor\log_pn\rfloor}\lfloor\frac{n}{p^i}\rfloor\)
对于每一个质数都用如上方式
共有 \(\frac{n}{\ln n}\) 个数,每次处理 \(\log n\) 的复杂度,总复杂度 \(O(n)\) 。

 

求解正约数集合:

试除法 求 \(n\) 的正约数:

时间复杂度 \(O(\sqrt n )\)

代码
int divisor[10010], cnt = 0;
for(int i=1; i<=sqrt(n); ++i) {
	if(n % i == 0) {
		divisor[++cnt] = i;
		if(i != n/i) divisor[++cnt] = n/i;
	}
}

推论:一个整数 \(n\)的正约数个数最多不超过 \(2\times \sqrt n\) 个

 

倍数法 求\(1\sim n\)的正约数:

先枚举 \(1 \sim n\) 中的每一个数作为约数 \(d\),再在 \(1\sim n\) 寻找 \(d\) 的倍数即可。时间复杂度 \(O(n+\frac{n}{2}+\cdots+\frac{n}{n})=O(n\log n)\)

代码
vecotr<int> divisor[500010];
for(int i=1; i<=n; ++i) { // 先枚举约数 i
	for(int j=1; j<=n/i; ++j) //枚举 i 在 1~n 范围内的倍数 i × j
		divisor[i*j].push_back(i); // i 是 i × j 的约数
}

推论:\(1\sim n\) 的约数个数总和大约为 \(n\log n\) 个。

 

约数研究

设 \(f(x)\) 为 \(x\) 的约数个数,求 \(\sum_{i=1}^nf(i)\)

可以枚举每一个 \(i\in[1,n]\) ,\(1\sim n\) 中含有 \(\lfloor\frac{n}{i}\rfloor\) 个约数 \(i\) 。所以答案为 \(\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor\)

 

\({\rm gcd}\) :

\(\forall a,b\in \mathbb{N},d\in \mathbb{N^{*}}\) 若 \(d\mid a\ \&\ d\mid b\) 则称 \(d\) 为 \(a,b\) 的公约数。

\(a,b\) 的公约数中最大的称为 \(a,b\) 的最大公约数,记为 \(\gcd(a,b)\)。

性质:

  • \(\gcd(a,b)=\gcd(b,a)\)
  • 对于 $\forall a,b\in \mathbb{N} $ 若 \({\rm gcd}(a,b)=1\) 则称 \(a,b\) 互质。
  • 由于任何正整数都是 \(0\) 和 \(0\) 的公约数,故 \(\gcd (0,0)\) 不存在。
  • 对于 \(\forall a\in \mathbb{N^{*}}\) ,有 \(\gcd(a,a)=a,\gcd(a,0)=a\) 。
  • \(\forall k\in \mathbb{Z}\),有 \(\gcd(k\times a,k\times b)=k\times \gcd(a,b)\) 。

 

更相减损术:

\(\forall a,b\in \mathbb{N^{*}}\ \&\ a\geq b\) 有 \(\gcd(a,b)=\gcd(b,a-b)=\gcd(a,a-b)\)

\(\forall d\mid a\ \&\ d\mid b\),有 \(a=k_1\times d,b=k_2\times d\) ,则 \((a-b)=(k_1-k_2)\times d\) ,所以 \(d\) 也是 \(b,a-b\) 的公约数,所以 \(\gcd(a,b)=\gcd(b,a-b)\)​ 。

 

辗转相除法:

\(\forall a,b\in \mathbb{N^{*}}\ \&\ b!=0\) 有 \(\gcd(a,b)=\gcd(b,a\bmod b)\)

  • 若 \(a<b\) ,则 \(\gcd(b,a\bmod b)=gcd(b,a)=gcd(a,b)\)
  • 若 \(a\geq b\) ,设 \(a=q\times b+r\) ,其中 \(0\leq r <b\) 。\(r=a\bmod b\) 。有 \(a=k_1\times d,q\times b=k_2\times d\) ,则 \(r=(a-q\times b)=(k_1-k_2)\times d\) ,因此 \(d\) ,也是 \(b,r\) 的公约数,故 \(\gcd(a,b)=\gcd(b,a\bmod b)\)

代码:

代码
int gcd(int a, int b) {
	while(b > 0 ) {
		int x = a % b;
		a = b;
		b = x;
	}
	return a;
}

递归:

代码
int gcd(int a, int b) {
	return b ? gcd(b, a%b) : a;
}

最大复杂度 \(O(\log(a+b))\)

 

\({\rm lcm}\):

\(\forall a,b\in\mathbb{N^{*}},m\in \mathbb{N}\) 若 \(a\mid m\ \&\ b\mid m\),则称 \(m\) 为 \(a\) 和 \(b\) 的公倍数。

\(a,b\) 的公倍数中最小的称为 \(a,b\) 的最小公倍数,记为 \({\rm lcm}(a,b)\) 。

\[{\rm lcm}(a,b)=\frac{a\times b}{\gcd(a,b)} \]

实际代码中: \({\rm lcm(a,b)=\frac{a}{\gcd(a,b)}\times b}\)

 

gcd与lcm

给出某两个整数 \(a\) 和 \(b\) (\(a\leq b\))的最大公约数 \(GCD\) 和最小公倍数 \(LCM\) ,请找出满足的 \(a\) 和 \(b\) ,使得 \(b-a\) 的值最小。

\(\because LCM=\frac{a\times b}{GCD}\)
\(\therefore \frac{a\times b}{GCD^2}=\frac{LCM}{GCD} \Rightarrow (\frac{a}{GCD})^2\leq \frac{LCM}{GCD}\)
\(\therefore \frac{a}{GCD}\leq \sqrt{\frac{LCM}{GCD}}\)
设 \(a'=\frac{a}{GCD}\) ,从 \(\sqrt{\frac{LCM}{GCD}}\sim 1\) 来枚举 \(a'\) ,当 \(a'\mid \frac{LCM}{GCD}\&\& \gcd(a',LCM/GCD/a')=1\) 时停止枚举。
答案即为 \(a=a'\times GCD,b=\frac{LCM}{a'}\)

 

CF1152C

给定两个正整数 \(a,b\) ,找到非负整数 \(k\) 使 \(a+k\) 与 \(b+k\) 的最小公倍数最小,如有多解输出最小的 \(k\) 。

设 \(a>b\) 显然 \({\rm lcm}(a+k,b+k)=\frac{(a+k)(b+k)}{\gcd(a+k,b+k)}\)
由辗转相除法可知 \(\gcd(a,b)=\gcd(b,a-b)\)
所以 \({\rm lcm}(a+k,b+k)=\frac{(a+k)(b+k)}{\gcd(b+k,a-b)}\)
所以可以枚举 \(a-b\) 的因子 \(w\) ,若 \(b\%w=0\) 则 \(k=0\) ,否则 \(k=(\lfloor\frac{b}{w}\rfloor+1)w-b\)
by ysx

标签:约数,frac,gcd,数论,质数,times,int
From: https://www.cnblogs.com/classblog/p/18326121

相关文章

  • 基础数论 整除分块与欧拉函数
    整除分块:例题:已知\(f(n)=\sum\limits_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloor\),给定\(n\),求\(f(n)\)的值。固然可以\(O(n)\)暴力,但显然会\(TLE\)。计算一下前几项的值之后可以发现\(\left\lfloor\frac{n}{i}\right\rfloor\)的取值在连续的一段区间内是......
  • 基础数论 模运算与逆元
    模运算与逆元:取模定义:\[a\bmodn\begin{cases}a-\lfloor\frac{a}{n}\rfloor\timesn\\\\\a\geq0\\-(-a\bmodn)\\\a<0\end{cases}\]取模基本性质:设\(a_0=a\bmodn,b_0=b\bmodn\)\((a+b)\bmodn=((a\bmodn)+(b\bmodn))\bmodn\)......
  • 数论
    数论基础整除只在整数域上讨论。一般形式为\(a|b\),叫做\(a\)能整除\(b\)。其性质在此不过多叙述。约数与整除相关。若\(a|b\),则称\(b\)是\(a\)的倍数,\(a\)是\(b\)的约数。在具体问题中,如果没有特别说明,约数总是指正约数。最大公因数和最小公倍数即\((a,b......
  • 【数论】1 矩阵快速幂(斐波那契)
    Tips:本篇blog适合刚开始学习数论部分的同学本题解仅代表个人思路,如有异议欢迎批评指正,谢谢一.概述该章节讲述的是矩阵运算及快速幂的概念,学过的同学可以跳过本章,直接看矩阵快速幂1.矩阵矩阵类似于向量,我们可以这么来表示一个矩阵如上图,表示了一个  的矩阵。矩阵也......
  • AcWing871. 约数之和
    题目链接:https://www.acwing.com/problem/content/description/873/题目叙述:给定n个正整数ai,请你输出这些数的乘积的约数之和,答案对10^9+7取模。输入格式第一行包含整数n。接下来n行,每行包含一个整数ai。输出格式输出一个整数,表示所给正整数的乘积的约数之和,答案需对......
  • AcWing 870. 约数个数
    题目叙述:题目链接:https://www.acwing.com/video/295/给定n个正整数ai,请你输出这些数的乘积的约数个数,答案对1e9+7取模。输入格式第一行包含整数n。接下来n行,每行包含一个整数ai。输出格式输出一个整数,表示所给正整数的乘积的约数个数,答案需对1e9+7取模。数据范......
  • 洛谷P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题
    [NOIP2001普及组]最大公约数和最小公倍数问题题目描述洛谷题目链接:https://www.luogu.com.cn/problem/P1029输入两个正整数x,y,求出满足下列条件的P,Q的个数:P,Q是正整数。要求P,Q以x为最大公约数,以y为最小公倍数。试求:满足条件的所有可能的P,Q的个数。......
  • 约数和倍数的性质
    约数(Divisors)约数是指能整除某个整数的其他整数。例如,对于整数(a),如果存在整数(b)使得(a=b*c),那么(b)就是(a)的约数。性质:1和自身是每个整数的约数:每个整数(a)都有至少两个约数:1和(a)本身。约数的范围:如果(d)是(n)的一个约数,则(d......
  • 初等数论入门
    整除性定义1如果\(a\)和\(b\)为整数且\(a\neq0\),我们说\(a\)整除\(b\)是指存在整数\(c\)使得\(b=ac\)。如果\(a\)整除\(b\),我们还称\(a\)是\(b\)的一个因子,且称\(b\)是\(a\)的倍数。如果\(a\)整除\(b\),则将其记为\(a|b\),如果\(a\)不能整除\(b\)......
  • 数论函数基础
    数论函数基础数论函数是数论中相当重要的一环,我们先来将*一些基本的函数——\(\color{black}\textsf{H}\color{red}\textsf{\_W\_Y}\)*:同“讲”,讲述全文绝大多数内容是对[0]中讲述的粗略抄写和胡乱加工关于加性函数和积性函数的部分,参考[3]1......