约数
约数
PS:以下讨论的任意都在正整数范围内。
若对于数字 \(d\) 与 \(n\),如果 \(\exists k\in \mathbb{Z}\),使 \(k\times d=n\)。则称 \(d\) 是 \(n\) 的约数,记为 \(d|n\)。\(n\) 是 \(d\) 的倍数。
否则 \(d\) 不是 \(n\) 的约数,记为 \(d\nmid n\)。
求 \(n\) 的正约数集合——试除法
枚举 \(1\sim \sqrt n\) 的所有数字 \(x\),判断 \(n\) 是否能够被 \(x\) 整除,若能则 \(x\) 与 \(n\div x\) 都是 \(n\) 的约数。
vector<int>Apx(int n) {
int cnt=sqrt(n);
vector<int>res;res.clear();
for(int i=1;i<=cnt;++i) {
if(n%i) continue;
res.push_back(i);
if(i*i==n) continue;
res.push_back(n/i);
}
return res;
}
推论:
-
除完全平方数的 \(\sqrt n\) 以外,所有约数成对出现。
-
\(n\) 的约数个数小于 \(2\times \sqrt n\)。
求 \(1\sim n\) 中每个数的正约数集合——倍数法。
朴素扫描 \(1\sim n\) 所有数并暴力 \(\sqrt n\) 找约数,时间复杂度高达 \(O(n\sqrt n)\)。
考虑对于 \(1\le i\le n\),找 \(i\) 在 \(n\) 以内的倍数。
时间复杂度 \(O(n\log n)\)。
vector<int>Ap[N];
void Init() {
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i) Ap[j].push_back(i);
return ;
}
推论:
- \(1\sim n\) 中所有数的约数个数和约为 \(n\log n\)。
算数基本定理(唯一分解定理)
\(\forall x\in \mathbb{N+},x\ne 1,\exist \{p_m\},\{c_m\},p_i\in \mathbb{P},x=\prod_{i=1}^m {p_i}^{c_i}\).
通俗来讲,就是任何一个不等于 \(1\) 的正整数都可以拆成若干个质数的乘积的形式。
证明:反证法。假设存在一些大于 \(1\) 的数不可拆分成若干质数乘积的形式。
设其中最小的一个数是 \(k\)。
由定义知,\(k\) 不是质数就是合数。
若 \(k\) 为质数,拆分 \(k=k\) 显然存在。
若 \(k\) 为合数,则被拆成 \(a\times b\) 的形式,由于 \(k\) 最小,所以 \(a,b\) 满足条件,所以 \(k\) 满足条件,与假设矛盾。故假设不成立,原命题成立。
证毕。
分解质因数——试除法
引理:对于一个数 \(x\),仅可能存在一个质因数大于 \(\sqrt x\)。
证明:假设存在两个大于 \(\sqrt x\) 的质因数 \(p,q\)(可能相等)。
由于分解的质因数相乘等于原数,所以 \(p\times q\) 应小于等于 \(x\),但是显然,\(p\times q\) 大于 \(x\)。
与命题矛盾,故假设不成立,原命题成立。
证毕。
所以只需扫描 \(1\sim \sqrt n\) 的所有质数并分解至无法再分,最后判唯一大于 \(\sqrt n\) 的质数即可。
时间复杂度 \(O(\sqrt n)\)。
vector<pair<int,int> >Pa;
void Prime(int x) {
int cnt=sqrt(x);
FOR(i,2,cnt) {
if(x%i) continue;
int cnt=0;
while(x%i==0) {
cnt++;
x/=i;
}
Pa.push_back(mkp(i,cnt));
}
if(x>1) Pa.push_back(mkp(x,1));
}
性质:
若 \(x=\prod _{i=1}^m {p_i}^{c_i}\),则:
- \(x\) 的正约数个数为:\(\prod_{i=1}^m (c_i+1)\).
证明:依次考虑所有质因子。
第 \(i\) 个质因子可以选 \(0\) 个、选 \(1\) 个、选 \(2\) 个 \(\dots\) 选 \(c_i\) 个。
有 \(c_i+1\) 种选择。
因为考虑每个质因子是分步进行,故分步乘法原理得证。
证毕。
- \(x\) 的正约数之和为 \(\prod_{k=1}^m (\sum_{i=0}^{c_k} p_k^i)\)。
最大公约数与最小公倍数
对于数字 \(x\),\(y\)。若存在数字 \(d\)。使 \(d\mid x\) 且 \(d\mid y\)。则称 \(d\) 为 \(x\) 与 \(y\) 的公约数。
其中最大的 \(d\) 称为 \(x\) 与 \(y\) 的最大公约数。写作 \(\gcd(a,b)\)。
对于数字 \(x\),\(y\)。若存在数字 \(d\)。使 \(x\mid d\) 且 \(y\mid d\)。则称 \(d\) 为 \(x\) 与 \(y\) 的公倍数。
其中最小的 \(d\) 称为 \(x\) 与 \(y\) 的最小公倍数。写作 \(\operatorname{lcm}(a,b)\)。
若 \(\gcd(x,y)=1\),则称 \(x\) 与 \(y\) 互质。
对于更多数的情况,\(\gcd(x,y,z)=1\) 称为 \(x,y,z\) 互质,称 \(\gcd(x,y)=\gcd(y,z)=\gcd(x,z)=1\) 为 \(x,y,z\) 两两互质。
规定:\(\gcd(a,0)=a\),\(\gcd(0,0)\) 不存在。
性质
-
对于任意 \(x,y\),有 \(\operatorname{lcm}(x,y)=\frac{x\times y}{\gcd(x,y)}\)。
-
\(\gcd(\frac{x}{\gcd(x,y)},\frac{y}{\gcd(x,y)})=1\)。
证明:反证法。设 \(x=\gcd(x,y)\times k_1\),\(y=\gcd(x,y)\times k_2\)。
那么上式等价于 \(\gcd(k_1,k_2)=1\)。
假设 \(\gcd(k_1,k_2)=d(d>1)\),那么设 \(z_1=\frac{k_1}{d},z_2=\frac{k_2}{d}\)。
那么 \(x=(\gcd(x,y)\times d)\times z_1,y=(\gcd(x,y)\times d)\times z_2\)。
由于 \(x,y\) 有公因子 \(\gcd(x,y)\times d\),与 \(\gcd(x,y)\) 最大矛盾。
故假设不成立,原命题成立。
证毕。
- 若 \(k_2\mid (k_1\times d)\) 且 \(\gcd(k_1,k_2)=1\),则有 \(k_2\mid d\)。
简证:若 \(k_2\nmid d\),则 \(k_2\nmid d\times k_1\),与条件矛盾。
证毕。
- 对于任意 \(d\mid x\) 且 \(d\mid y\),有 \(d\mid \gcd(x,y)\)。
证明:设 \(d_2=gcd(x\div d,y\div d)\),那么 \(x\) 与 \(y\) 的最大公因子是 \(d\times d_2=gcd(x,y)\)。
显然,\(d_2\) 是整数。
证毕。
- 对于任意 \(x\mid d\) 且 \(y\mid d\),有 \(\operatorname{lcm}(x,y)\mid d\)。
证明:设 \(x=k_1\times \gcd(x,y),y=k_2\times \gcd(x,y)\)。
显然有 \(k_1\mid \frac{d}{\gcd(x,y)}\),\(k_2\mid \frac{d}{\gcd(x,y)}\).
因为 \(k_1,k_2\) 互质,故 \((k_1\times k_2)\mid \frac{d}{\gcd(x,y)}\).
故 \(k_1\times k_2\times \gcd(x,y)\mid d \rightarrow \operatorname{lcm}(a,b)\mid d\)。
证毕。
- \(\gcd(a\times n,b\times n)=n\times \gcd(a,b)\)。
简证:将 \(a,b\) 同时乘 \(n\),其公因子又多了 \(n\times \gcd(a,b)\)。显然最大。
证毕。
重要性质
- \(\gcd(a,\operatorname{lcm} _{i=1}^n b_i)=\operatorname{lcm}_{i=1}^n \gcd(a,b_i)\)。
\(\operatorname{Proof}\):数学归纳法,当 \(n=1\) 时,原式等价于 \(\gcd(a,b_1)=\gcd(a,b_1)\) 显然成立。
设命题在 \(n=k\) 时成立,当 \(n=k+1\) 时:
\[\gcd(a,\operatorname{lcm}_{i=1}^{k+1} b_i)=\gcd(a,\frac{(\operatorname{lcm}_{i=1}^k b_i)\times b_{k+1}}{\gcd(\operatorname{lcm}_{i=1}^k b_i,b_{k+1})}) \]设 \(z=\frac{b_{k+1}}{\gcd(\operatorname{lcm}_{i=1}^k b_i,b_{k+1})}\)
则上式等价于:
\[\begin{aligned} \gcd(a,\operatorname{lcm}_{i=1}^{k+1} b_i)&=\gcd(a,(\operatorname{lcm}_{i=1}^{k} b_i)\times z)\\ &=\gcd(a,\operatorname{lcm}_{i=1}^{k} b_i)\times \gcd(a,z)\\ &=(\operatorname{lcm}_{i=1}^k \gcd(a,b_i)) \times \gcd(a,z)\\ &=\operatorname{lcm}_{i=1}^{k+1} \gcd(a,b_i) \end{aligned} \]最后一步成立是因为 \(\gcd(a,z)\) 一定包含的是 \(\operatorname{lcm}_{i=1}^k b_i\) 没有的质因子,所以可以直接乘(玄学)。
证毕。
求解最大公约数的方法
更相减损术: 若 \(a>b\),\(\gcd(a,b)=\gcd(a,a-b)=\gcd(b,a-b)\)。
欧几里得算法 \(\gcd(a,b)=\gcd(b,a \bmod b)\)。(\(a \bmod b\) 表示 \(a\div b\) 的余数。)
证明:若 \(a<b\),命题显然成立。
若 \(a\ge b\),设 \(a=q\times b+r\),即 \(r=a\bmod b\)。
设 \(d\) 为 \(a,b\) 的任意一个公约数。
由于 \(d\mid a,d\mid (b\times q)\),所以 \(d\mid (a-q\times b)\),即 \(d\mid r\)。
所以 \(a,b\) 的公约数集合与 \(b,a\bmod b\) 的公约数集合相同,其最大值自然相同。
证毕。
int gcd(int a,int b) {
return b?gcd(b,a%b):a;
}
时间复杂度约 \(O(\log (a+b))\)。
欧拉函数
定义函数 \(\varphi (n)\) 表示 \(1\sim n\) 中与 \(n\) 互质的数的个数。
\(\varphi (n)\) 就是大名鼎鼎的欧拉函数。
求法: 若将 \(n\) 分解质因数为 \(n=\prod _{i=1}^m p_i^{c_i}\)。
则有:
证明:设 \(n\) 存在质因子 \(p\),则 \(1\sim n\) 中 \(p\) 的倍数有 \(p,2\times p,3\times p,\dots ,(n\div p) \times p\) 共 \(n\div p\) 个。
在设 \(n\) 存在另一种质因子 \(q\),则 \(1\sim n\) 中 \(q\) 的倍数有 \(q,2\times q,3\times q,\dots ,(n\div q) \times q\) 共 \(n\div q\) 个。
由于会去掉两次 \(p\times q\) 的倍数,所以还要加上 \(n\div(p\times q)\)。
故数量为 \(n-\frac{n}{p}-\frac{n}{q}+\frac{n}{p\times q}=n(1-\frac{1}{p})(1-\frac{1}{q})\)。(容斥原理)
对 \(n\) 的全部质因子使用容斥原理,命题得证。
所以只需对 \(n\) 分解质因数,即可顺便求欧拉函数。
int phi(int x) {
int cnt=sqrt(x),res=x;
FOR(i,2,cnt) {
if(x%i) continue;
while(x%i==0) x/=i;
res/=i;res*=(i-1);
}
if(x>1) res/=x,res*=(x-1);
return res;
}
性质:
- \(1\sim n\) 中与 \(n\) 互质的数的和为 \(\frac{n\times \varphi(n)}{2}\)。
证明:设 \(1\sim n\) 中与 \(n\) 互质的数构成的数列为 \(p_1,p_2,p_3,\dots ,p_{\varphi(n)}\)。
显然,\(p_1=1,p_{\varphi(n)}=n-1\)。
类比等差数列求和,可得对应相加之和为 \(n\times \varphi(n)\),除以 \(2\) 则命题得证。
证毕。
- 若 \(\gcd(a,b)=1\),则 \(\varphi(ab)=\varphi(a)\times \varphi(b)\)。
简证:由于 \(a\) 与 \(b\) 互质,故 \(a\) 与 \(b\) 的质因子类别交集为空。
故得证。
其实,若函数 \(f\) 满足 \(f(ab)=f(a)\times f(b)\):
\(\hspace{1cm}\) - 若 \(a,b\) 互质,则称函数 \(f\) 为积性函数。
\(\hspace{1cm}\) - 若 \(a,b\) 不一定互质,则称函数 \(f\) 为完全积性函数。
- 若 \(n\) 分解质因数后为 \(\prod _{i=1}^m p_i^{c_i}\),\(\varphi(n)=\prod _{i=1}^m \varphi(p_i^{c_i})\)。
简证:不同质因子的若干次幂之间显然互质,根据性质 \(2\) 得证。
事实上,该性质对所有积性函数都成立。
- 对于一个数 \(p\in \mathbb{P}\):
\(\hspace{1cm}\) - 若 \(d\mid n\) 则 \(\varphi(n\times p)=\varphi(n)\times p\)。
\(\hspace{1cm}\) - 若 \(d\nmid n\) 则 \(\varphi(n\times p)=\varphi(n)\times (p-1)\)。
证明:设 \(n\) 分解质因数后为 \(\prod _{i=1}^m p_i^{c_i}\)。
对于第一种情况,\(p\) 必然是 \(p_i\) 的其中一个。
故 \(\varphi(n\times p)=n\times p\times \prod _{i=1}^m(1-\frac{1}{p_i})=\varphi(n)\times p\)。
对于第二种情况:
\(\varphi(n\times p)=n\times p\times \prod _{i=1}^m(1-\frac{1}{p_i})\times (1-\frac{1-p})=\varphi(n)\times p\times (1-\frac{1}{p})=\varphi(n)\times p-1\)。
证毕。
- \(\sum_{d\mid n} \varphi(d)=n\)
证明:令 \(f(n)=\sum_{d\mid n} \varphi(d)\)。
设 \(m\) 与 \(n\) 互质。\(f(m)=\sum_{d\mid n} \varphi(d)\)。
\(f(nm)=\sum_{d\mid nm} \varphi(d)=(\sum_{d\mid n} \varphi(d))(\sum_{d\mid m} \varphi(d))=f(n)\times f(m)\).
所以 \(f\) 是积性函数,满足性质 \(3\)。
故 \(f(n)=\prod _{i=1}^m f(p_i^{c_i})\)。
由于 \(f(p_i^{c_i})=\sum_{j=0}^{c_i} \varphi(p_i^j)=1+\sum_{j=1}^{c_i} p_i^{j-1}\times (p_i-1)=1+\frac{(p_i-1)\times (p_i^{c_i}-1)}{p_i-1}=1+p_i^{c_i}-1=p_i^{c_i}\)
即 \(f(p_i^{c_i})=p_i^{c_i}\)。
故 \(f(n)=\prod_{i=1}^m f(p_i^{c_i})=\prod_{i=1}^m p_i^{c_i}=n\).
即 \(\sum_{d\mid n} \varphi(d)=n\).
证毕。
欧拉函数递推
\(Q:\) 求 \(1\sim n\) 之间所有数的欧拉函数。
当然可以 \(O(n\sqrt n)\) 直接暴力一个个求,\(n\le 1\times 10^6\) 直接炸。
根据性质 \(4,5\),可以根据质数 \(p\) 从 \(\varphi(n)\) 递推到 \(\varphi(n\times p)\)。
所以可以通过 Eratosthenes 筛法或欧拉筛法来线性地递推欧拉函数。
Eratosthenes:
bool vis[N];
int phi[N];
void Eratosthenes() {
FOR(i,1,n) phi[i]=i;
FOR(i,2,n) {
if(vis[i]) continue;
for(int j=i;j<=n;j+=i)
phi[j]/=i,phi[j]*=(i-1),vis[j]=1;
}
}
时间复杂度 \(O(n\log\log n)\)。
欧拉:
int v[N],phi[N];
vector<int>prime;
void Euler() {
FOR(i,1,n) phi[i]=i;
FOR(i,2,n) {
if(!v[i]) v[i]=i,phi[i]=i-1,prime.push_back(i);
for(int p:prime) {
if(p*i>n||v[i]<p) break;
v[i*p]=p;
phi[p*i]=phi[i]*(i%p?p-1:p);
}
}
}
时间复杂度 \(O(n)\)。
整除分块
对于以下的式子:
这个式子直接求是 \(O(n)\) 的。
性质:
- 加数最多出现 \(2\times \sqrt n\) 种,且同种加数连续。
简证:显然,加数只会是 \(n\) 的约数,而 \(n\) 的约数小于 \(2 \sqrt n\)。
由于加数的分母单调递增,分子不变,故加数单调不增。
证毕。
考虑枚举每一种加数,求出该种加数对应的区间,答案加上区间长度乘此加数即可。
设当前区间左端点为 \(l\),则此区间对应的值为 \(\lfloor \frac{n}{l} \rfloor\)。
如果能求出右端点 \(r\),就可以求出该区间对应的贡献,还可以顺便求出下一个区间的左端点 \(l'=r+1\)。
所以现在的问题就是如何求 \(r\)。
设 \(k\) 为当前区间的值。
则应满足 \(r\times k\le n\)。
所以 \(r\le \frac{n}{k}\)。
又因为要取最大的 \(r\) 并且 \(r\) 为整数。
故 \(r=\lfloor \frac{n}{k}\rfloor=\lfloor \frac{n}{\lfloor \frac{n}{l} \rfloor} \rfloor\)。
时间复杂度:由于区间数量最多 \(2\times \sqrt n\) 个,所以时间复杂度为 \(O(\sqrt n)\)。
int ans=0;
for(int l=1,r;l<=n;l=r+1) {
r=(n/(n/l));
ans+=(r-l+1)*(n/l);
}
cout<<ans<<'\n';