数论专题笔记
1 数论中的基础知识
1.1 整除
1.1.1 定义
设
1.1.2 定理
- (反射性)对于所有整数
a ,满足a \mid a 。 - (传递性)若
a \mid b ,b \mid c ,则a \mid c 。 - 若
a,b_1,b_2,\cdots,b_n 都是整数,且a \mid b_i (1 \le i \le n ),则a \mid b_1c_1+b_2c_2+\cdots+b_nc_n (\forall c_1,c_2,\cdots,c_n \in \mathbb{Z} )。 - 若
a,b_1,b_2,\cdots,b_n 都是整数,且a \mid b_i (1 \le i \le n ),则a \mid b_1c_1 \times b_2c_2 \times \cdots \times b_nc_n (\forall c_1,c_2,\cdots,c_n \in \mathbb{Z} )。 - 若
a \mid b ,a \mid b \pm c ,则a \mid c 。 - 若整数
a,b,c,d,e 满足a \mid b-c ,a \mid d-e ,则a \mid bd - ce 。 - 若
a\mid b ,则\forall c \in \mathbb{Z} ,ac\mid bc ;若ac \mid bc 且c \ne 0 ,则a\mid b 。
1.1.3 证明
定理 1、2、7 可直接由定义推导,定理 3-6 通过将
1.2 同余
1.2.1 定义
设
1.2.2 定理
- (反射性)
a \equiv a \pmod n 。 - (对称性)若
a \equiv b \pmod n ,则b \equiv a \pmod n 。 - (传递性)若
a \equiv b \pmod n 且b \equiv c \pmod n ,则a \equiv c \pmod n 。 - 若
a \equiv c \pmod n 且b \equiv d \pmod n ,则a+b \equiv c+d \pmod n ,ab \equiv cd \pmod n 。 - 若
a \equiv b \pmod n ,则ac \equiv bc \pmod {nc} ;若ac \equiv bc \pmod {nc} 且c \ne 0 ,则a \equiv b \pmod n 。
1.2.3 证明
定理 1、2 由定义直接成立;定理 3-5 利用整除性质推导,例如定理 3 可通过
1.3 数论函数
定义域为正整数、值域为复数集子集的函数称为数论函数。
1.3.1 积性函数
- 积性函数:
\forall x,y \in \mathbb{N}_+ 且\gcd(x,y)=1 ,满足f(xy)=f(x)f(y) 。 - 完全积性函数:
\forall x,y \in \mathbb{N}_+ ,满足f(xy)=f(x)f(y) (完全积性必为积性)。 - 常见积性函数:
- 1 函数(完全积性):
\mathbb{1}(n)=1 - 幂函数(完全积性):
id_k(n)=n^k - 狄利克雷卷积单位元(完全积性):
\varepsilon(n)= \begin{cases} 1, & n=1 \\ 0, & n \ne 1\end{cases} - 欧拉函数:
\varphi(n) (1\sim n 中与n 互质的数的个数) - 除数函数:
d(n) (n 的正因子个数)
- 1 函数(完全积性):
1.3.2 加性函数
- 加性函数:
\forall x,y \in \mathbb{N}_+ 且\gcd(x,y)=1 ,满足f(xy)=f(x)+f(y) 。 - 完全加性函数:
\forall x,y \in \mathbb{N}_+ ,满足f(xy)=f(x)+f(y) (完全加性必为加性)。 - 常见加性函数:
-
1.4 模运算
带余除法:
运算法则:
-
(a+b) \bmod M = (a \bmod M + b \bmod M) \bmod M -
(a-b) \bmod M = (a \bmod M - b \bmod M) \bmod M -
(a \times b) \bmod M = (a \bmod M \times b \bmod M) \bmod M
注意:除法无直接模运算法则,需通过逆元转换。
2 素数
2.1 唯一分解定理
每个大于
推论:
分解代码:
void decompose(int x){
for(int i=2;i*i<=x;++i)
while(x%i==0) ++a[i],x/=i;
if(x) ++a[x];
}
int main(){
int n;scanf("%d",&n);
decompose(n);
for(int i=1;i<=n;++i)
if(a[i]) printf("%d %d\n",a[i],i);
}
2.2 费马小定理若
5 模意义下的乘法逆元
5.1 定义
若
5.2 逆元求法
5.2.1 扩展欧几里得求逆元
将
5.2.2 费马小定理求逆元
- 常见卷积:
1*\varphi=id ,1*\mu=\varepsilon
8.1.2 莫比乌斯函数
8.2 莫比乌斯反演
- 形式 1:若
g(x)=\sum_{k|x} f(k) ,则f(x)=\sum_{k|x} \mu(x/k)g(k) 。 - 形式 2:若
g(x)=\sum_{x|k} f(k) ,则f(x)=\sum_{x|k} \mu(k/x)g(k) 。
8.3 整除分块
用于快速计算
for (int l = 1, r; l <= n; l = r + 1)
r = n / (n / l),
ans += (r - l + 1) * (n / r);
8.4 杜教筛
快速求积性函数前缀和,核心公式:
(其中
const int N = 5e6 + 5;
int miu[N], p[N];
bool is_p[N];
map <int, int> mp;
void sieve(int N) {
miu[1] = 1;
for (int i = 2; i <= N; i++) {
if (!is_p[i]) p[++c] = i, miu[i] = -1;
for (int j = 1; j <= c && i * p[j] <= N; j++) {
is_p[i * p[j]] = 1;
if (i % p[j] == 0) { miu[i * p[j]] = 0; break; }
miu[i * p[j]] = -miu[i];
}
}
for (int i = 2; i <= N; i++) miu[i] += miu[i - 1];
}
int cal_miu(int x) {
if (x <= 5e6) return miu[x];
if (mp.count(x)) return mp[x];
int res = 1;
for (int l = 2, r; l <= x; l = r + 1)
r = x / (x / l),
res -= (r - l + 1) * cal_miu(x / r);
return mp[x] = res;
}
8.5 Powerful Number 筛(PN 筛)
适用于杜教筛无法解决的函数,核心是利用“幂数”(所有质因子次数
模板代码(Min_25 筛替代):
const int mod = 1e9 + 7;
const int inv2 = 500000004;
const int inv6 = 166666668;
const int N = 5e6 + 5;
int p[1000000], phi[N], c;
bool is_p[N];
void sieve(int N) {
phi[1] = 1;
for (int i = 2; i <= N; i++) {
if (!is_p[i]) p[++c] = i, phi[i] = i - 1;
for (int j = 1; j <= c && i * p[j] <= N; j++) {
is_p[i * p[j]] = 1;
if (i % p[j] == 0) { phi[i * p[j]] = phi[i] * p[j]; break; }
phi[i * p[j]] = phi[i] * (p[j] - 1);
}
}
for (int i = 2; i <= N; i++) (phi[i] *= i) %= mod;
for (int i = 2; i <= N; i++) (phi[i] += phi[i - 1]) %= mod;
}
int mp[N], n, ans;
int cal_G(int x) {
if (x <= 5e6) return phi[x];
if (mp[n / x]) return mp[n / x];
int X = x % mod;
int res = X * (X + 1) % mod * (2 * X + 1) % mod * inv6 % mod;
for (int l = 2, r; l <= x; l = r + 1)
r = x / (x / l),
res -= (l + r) % mod * (r - l + 1) % mod * inv2 % mod * cal_G(x / r);
return mp[n / x] = res;
}
void dfs(int nw, int num, int H) {
if (nw > c || num * p[nw] > n) {
(ans += H * cal_G(n / num)) %= mod;
return;
}
dfs(nw + 1, num, H);
for (int mu = p[nw] * p[nw], s = 1; num * mu <= n; mu *= p[nw], s++)
dfs(nw + 1, num * mu, s * (p[nw] - 1) % mod * mu % mod * H % mod);
}
signed main() {
scanf("%lld", &n), sieve(5e6), dfs(1, 1, 1);
printf("%lld", ans);
}