数论学习笔记
数论学习笔记
定义
一些概念
- 数论函数(算术函数)
定义域为正整数,陪域为复数的函数。每个算术函数都可视为复数的序列。
最重要的算术函数是积性及加性函数。算术函数的最重要操作为狄利克雷卷积。
- 积性函数
满足
则 \(f\) 是积性函数。
同理有加性函数
- 完全积性函数
同理有完全加性函数
- 艾弗森约定(艾佛森括号)
- **符号函数 **
一些数论函数
- 欧拉函数
\(\varphi(n)\) 是小于等于 \(n\) 的正整数中与 \(n\) 互质的数的数目
- 恒等函数
- 单位函数
- 幂函数
- 单位元函数
- 莫比乌斯函数
- 约数个数函数
- 约数和函数
狄利克雷卷积
定义
卷积(又称叠积(convolution)、褶积或旋积),是透过两个函数 \(f\) 和 \(g\) 生成第三个函数的一种数学算子。狄利克雷卷积是其中的一种。
狄利克雷卷积是定义在数论函数集上的一种二元运算,相当于是在这个定义上的一种乘法,而普通函数加法就是该定义上的加法。
运算
就和一般实数上的乘法与加法十分类似
-
交换律: \(f\ast g=g\ast f\)
-
结合律: \((f\ast g)\ast h=f\ast(g\ast h)\)
-
分配率: \(f\ast (g+h)=f\ast g + f\ast h\)
正如实数中有 \(\forall n,\ 1\times n=n\) 及 \(\forall n\ne0,\ n\times n^{-1}=1\) 一样,这里也存在**单位元函数 \(\varepsilon\) **,使得
- \(\forall f,\ f\ast\varepsilon=\varepsilon\ast f=f\)
- \(\forall f(1)\ne0,\ f\ast f^{-1}=\varepsilon\)
定理
一些定理
- 两个积性函数的狄利克雷卷积一定也是一个积性函数。
一些等式
证明 \((4)\) :
即 \(I\) 与 \(\mu\) 互为反函数, \(I=\mu^{-1},\ \mu=I^{-1}\)
证明 \((7)\) :
莫比乌斯反演
性质
莫比乌斯函数不仅是积性函数,还有如下性质:
结论
结论 1
称数论函数 \(F(n)\) 为数论函数 \(f(n)\) 的莫比乌斯变换,数论函数 \(f(n)\) 为数论函数 \(F(n)\) 的莫比乌斯逆变换(反演)。
证明:
结论 2
证明:
应用:
例 1
模板代码
线性筛
许多积性函数对质数有特殊性质,使得我们可以简单地计算函数值,
同时,又因为任意两个质数互质,于是我们可以利用质数和数论函数的积性筛出更一般的数的函数值。
使用线性筛可以 \(O(n)\) 地筛出大部分积性函数的值。
欧拉函数
#include <vector>
#include <bitset>
int n, phi[N];
std::vector<int> prime;//筛出的质数
std::bitset<N> cmpst;//composite 合数
inline void Euler() {
cmpst.reset();
phi[1] = 1;//特殊值
for (register int i=2, tmp; i<=n; ++i) {
if (!cmpst[i]) {
prime.push_back(i);
phi[i] = i-1;//质数的phi值
}
for (register int p : prime) {
tmp = i*p;
if (tmp > n) break;
cmpst[tmp] = 1;//标记合数
if (i%p == 0) {//线性筛的核心操作:此时p是i的最小质因数
phi[tmp] = phi[i] * p;
break;
} phi[tmp] = phi[i] * phi[p];//合数的phi值,利用phi的积性
}
}
}
莫比乌斯函数
#include <vector>
#include <bitset>
#define N 50030
int mu[N];
bitset<N> nap;//not a prime
vector<int> prime;
inline void seive(int n = N - 20) {
mu[1] = 1; nap[1] = 1;
for (rg int i=2; i<=n; ++i) {
if (!nap[i]) {
mu[i] = -1;
prime.push_back(i);
}
for (rg int p : prime) {
if (i * p > n) break;
nap[i * p] = 1;
if (i % p == 0) { mu[i * p] = 0; break; }
mu[i * p] = -mu[i];
}
}
}
整除分块(数论分块)
对于多组询问求形如下式的值
其中 \(S\) 与 \(f\) 都是可以 \(O(1)\) 求值的函数
我们可以使用整除分块将其从 \(O(n)\) 优化至 \(O(\sqrt n)\) 。
原理:当 \(i\) 在一些区间 \([l,r],\ l,r\in[1,n]\) 中时, \(\lfloor\frac ki\rfloor\) 为定值。
我们可以在预处理中将 \(f\) 前缀和为 \(sum\_f\)
已知 \(l,k\) ,我们可以 \(O(1)\) 求出 \(r=\lfloor\frac k{\lfloor \frac ki\rfloor}\rfloor\) 。证明。
特别注意:有时候 \(i>k\) 了就会出现除以 0 的情况。(易知当 \(k\ge n\) 时不会出现)
int ans = 0;
for (int l=1, r; l<=n; l=r+1) {
r = (l > k) ? n : min( k / (k / l), n );
ans += S(l) * ( num_f(r) - sum_f(l-1) );
}
return ans;
典型例题
GCD - Extreme (II)
\(1\le n\le4\times10^6+1\) ,数据组数: \(T\le100\) ,求:
解:
注意到:
于是我们定义 \(\varphi\) 的从 2 开始的前缀和 \(\operatorname{\varphi_s}(x)=\sum\limits_{i=2}^x\varphi(i)\) ,它可以用线性筛筛出来后 \(O(1)\) 求出。
那么继续:
利用整除分块,可以做到 \(O(n+T\sqrt n)\)
[NOI2010] 能量采集
本文来自博客园,作者:Gyan083,转载请注明原文链接:https://www.cnblogs.com/gyan083/p/15585300.html