P5325 【模板】Min_25 筛
Rigel
·
·
题解
0x00 引言
Min_25 筛可以在 \mathcal{O}\left( \dfrac{n^\frac{3}{4}}{\log n} \right) 或 \Theta(n^{1 - \epsilon}) 的复杂度下求一类积性函数的前缀和。
以下是前提条件。
-
对于质数 p,f(p) 是关于 p 的可快速求值的完全积性函数之和(例如多项式)。
-
对于质数 p,f(p^c) 可快速求值。
0x10 约定
0x20 正文
我们要计算的是 \mathrm{Ans} = \displaystyle\sum\limits_{i=1}^{n}f(i)。
注意到 F_1(n) = \displaystyle\sum\limits_{\substack{i \in [2,n] \\ \operatorname{lpf}(i) \ge 2}}f(i) = \displaystyle\sum\limits_{i=2}^{n}f(i)。
于是 \mathrm{Ans} = F_1(n) + f(1) = F_1(n) + 1。(积性函数 f(1) = 1)
考虑如何求出 F_k(n)。
首先,若 n < p_k,则 F_k(n) = 0。
否则,设 F_k(n) = \displaystyle\sum\limits_{\substack{t \in [2,n] \\ \operatorname{lpf}(t) \ge p_k}}f(t)。
考虑所有可能的 t。这些 t 一部分为质数,另一部分为合数。
::::info[当 t 为质数时]{open}
设 t = p_i。
则 \operatorname{lpf}(t) = p_i。
由 t \in [2,n],有 p_i \le n。
由 \operatorname{lpf}(t) \ge p_k,有 p_i \ge p_k。
我们要求的是 p_k \le p_i \le n 的 f(p_i) 之和。
$p_i < p_k$,即 $p_i \le p_{k-1}$ 的 $f(p_i)$ 之和为 $\displaystyle\sum\limits_{p_i \le p_{k-1}}f(p_i) = F_{\text{prime}}(p_{k-1})$。
因此,所有质数 $t$ 对 $F_k(n)$ 的贡献为:
$$F_{\text{prime}}(n) - F_{\text{prime}}(p_{k-1}).$$
::::
::::info[当 $t$ 为合数时]{open}
设 $t = p_i^c \cdot m$,满足 $\operatorname{lpf}(t) = p_i$ 且 $p_i \nmid m$。
考虑 $p_i$ 的取值范围。
首先 $p_i \ge p_k$,即 $i \ge k$。
由于 $\operatorname{lpf}(t) = p_i$,故 $p_i^2 \le t$。而 $t \le n$,故 $p_i^2 \le n$。
按 $m$ 的值分讨。
:::info[当 $m=1$ 时]{open}
此时 $t = p_i^c$。
考虑 $c$ 的取值范围。
首先 $p_i^c \le n$。
由于 $p_i^c$ 是合数,故 $c \ge 2$。
枚举 $p_i$ 和 $p_i$ 的次数 $c$,这部分的贡献为:
$$\sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 2\\p_i^c \le n}}f(p_i^c).$$
将 $c$ 用 $c+1$ 代换:
$$\sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^{c+1} \le n}}f(p_i^{c+1}).$$
:::
:::info[当 $m \ge 2$ 时]{open}
考虑 $c$ 的取值范围,显然有 $c \ge 1$ 且 $p_i^c \le n$。
考虑 $m$ 的约束条件。
首先 $t = p_i^c \cdot m \le n$,即 $m \le n/p_i^c$。
由于 $\operatorname{lpf}(t) = p_i$ 且 $p_i \nmid m$,所以 $\operatorname{lpf}(m) > p_i$,即 $\operatorname{lpf}(m) \ge p_{i+1}$。
故 $m$ 满足:$2 \le m \le n/p_i^c$ 且 $\operatorname{lpf}(m) \ge p_{i+1}$。
这些 $m$ 的 $f(m)$ 之和为 $\displaystyle\sum\limits_{\substack{m \in [2,n/p_i^c] \\ \operatorname{lpf}(m) \ge p_{i+1}}}f(m) = F_{i+1}(n/p_i^c)$。
枚举 $p_i$、$p_i$ 的次数 $c$ 和 $m$,这部分的贡献为:
$$\begin{aligned}
&\ \ \ \ \,\sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^c \le n}}\sum\limits_{\substack{m \in [2,n/p_i^c] \\ \operatorname{lpf}(m) \ge p_{i+1}}}f(p_i^c \cdot m)\\
&= \sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^c \le n}}f(p_i^c)\sum\limits_{\substack{m \in [2,n/p_i^c] \\ \operatorname{lpf}(m) \ge p_{i+1}}}f(m)\\
&= \sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^c \le n}}f(p_i^c)F_{i+1}(n/p_i^c).
\end{aligned}$$
考虑 $p_i^c \le n < p_i^{c+1}$ 的情况。
此时 $n/p_i^c < p_i$,而 $p_i < p_{i+1}$,故 $n/p_i^c < p_{i+1}$。
于是 $F_{i+1}(n/p_i^c)=0$。
因此当 $n \ge p_i^{c+1}$ 时,$F_{i+1}(n/p_i^c)$ 才可能有值。
将第二重求和的上界改为 $p_i^{c+1} \le n$,则这部分的贡献为:
$$\sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^{c+1} \le n}}f(p_i^c)F_{i+1}(n/p_i^c).$$
:::
综上,所有合数 $t$ 对 $F_k(n)$ 的贡献为:
$$\begin{aligned}
&\ \ \ \ \,\sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^{c+1} \le n}}f(p_i^{c+1}) + \sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^{c+1} \le n}}f(p_i^c)F_{i+1}(n/p_i^c)\\
&=\sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^{c+1} \le n}}\left( f(p_i^{c+1}) + f(p_i^c)F_{i+1}(n/p_i^c) \right).
\end{aligned}$$
::::
综上:
$$F_k(n) = F_{\text{prime}}(n) - F_{\text{prime}}(p_{k-1}) + \sum\limits_{\substack{i \ge k\\p_i^2 \le n}}\sum\limits_{\substack{c \ge 1\\p_i^{c+1} \le n}}\left( f(p_i^{c+1}) + f(p_i^c)F_{i+1}(n/p_i^c) \right).$$
其中,$F_{\text{prime}}(p_{k-1})$ 可在线性筛时维护得出,$f(p_i^c)$ 和 $f(p_i^{c+1})$ 可直接计算。难点在于 $F_{\text{prime}}(n)$。
假设现在已经求出了所有 $F_{\text{prime}}(n)$,那么有两种方式可以求出所有 $F_k(n)$:
1. 直接按照递推式递归计算。
2. 从大到小枚举 $p_i$ 转移,仅当 $p_i^2 < n$ 时转移增加值不为 $0$,故按照递推式后缀和优化即可。
---
现在考虑如何求出所有 $F_{\text{prime}}(n)$。
观察求 $F_k(n)$ 的过程,易得 $F_k(n)$ 只在形如 $n' = n/i$ 的点有值,$F_{\text{prime}}(n)$ 亦是如此。
:::info[证明]{open}
考虑类似于数学归纳法的证明方法。
首先 $n = n/1$,是 $n/i$ 的形式。
递归时,第一步 $n' = n/p_i^c$ 仍为 $n/i$ 的形式。
后续递归中,$n'/j = (n/i)/j = n/(ij)$,依然是 $n/i$ 的形式。
:::
这些 $n'$ 必然在集合 $S = \{ 1,2,3,\cdots,\lfloor\sqrt{n}\rfloor,n/\lfloor\sqrt{n}\rfloor,\cdots,n/3,n/2,n \}$ 中。
其中 $\lvert S \rvert = \Theta(\sqrt{n})$。
考虑如何求出所有 $F_{\text{prime}}(n')$。
设 $f(p) = \displaystyle\sum\limits_{i=1}^{r}a_i p^{c_i}$。
则:
$$\begin{aligned}
F_{\text{prime}}(n') &= \sum\limits_{p \le n'}f(p)\\
&= \sum\limits_{p \le n'} \sum\limits_{i=1}^{r}a_i p^{c_i}\\
&= \sum\limits_{i=1}^{r}a_i \sum\limits_{p \le n'} p^{c_i}.
\end{aligned}$$
考虑对于所有 $n'$,求出形如 $\displaystyle\sum\limits_{p \le n'} p^c$ 的式子。
设 $g(p) = p^c$。
设 $G_{\text{prime}}(n) = \displaystyle\sum\limits_{p \le n}g(p)$。
设 $G_k(n) = \displaystyle\sum\limits_{\substack{i \in [2,n] \\ \operatorname{lpf}(i) > p_k \lor \operatorname{isprime}(i)}} g(i)$,即**埃氏筛**第 $k$ 轮筛完后剩余的数的 $g(i)$ 之和。
显然 $G_{\text{prime}}(n)$ 与 $G_k(n)$ 也仅在形如 $n' = n/i$ 的点上有值。
考虑如何求出所有 $G_{\text{prime}}(n')$。(求出所有 $G_{\text{prime}}(n')$ 后即可得到所有 $F_{\text{prime}}(n')$)
对于合数 $x \le n$,必然有 $\operatorname{lpf}(x) \le \sqrt{x} \le \sqrt{n}$。
设 $\ell(n)$ 为小于等于 $\sqrt{n}$ 的最大质数的下标,则 $G_{\text{prime}}(n) = G_{\ell(n)}(n)$。因为在埃氏筛进行 $\ell(n)$ 轮后,剩下的均为质数。
考虑递推计算 $G_{\ell(n)}(n)$。
先算出 $G_0(n) = \displaystyle\sum\limits_{\substack{i \in [2,n] \\ \operatorname{lpf}(i) > 1 \lor \operatorname{isprime}(i)}} g(i) = \displaystyle\sum\limits_{i=2}^{n} g(i)$。(前面规定了 $p_0 = 1$)
考虑如何转移。
埃氏筛中第 $k$ 轮用 $p_k$ 筛去了**未被筛过的** $p_k$ 的倍数,设其为 $x = p_k \cdot m$。
满足:
- $\operatorname{lpf}(x) = p_k$。
- $\operatorname{lpf}(m) \ge p_k$。
考虑 $p_k^2$ 和 $n$ 的大小关系。
:::info[当 $p_k^2 > n$ 时]{open}
对于合数 $x \le n$,$\operatorname{lpf}(x) \le \sqrt{n}$。而 $n < p_k^2$,即 $\sqrt{n} < p_k$,也就是说 $\operatorname{lpf}(x) < p_k$。故 $\operatorname{lpf}(x)$ 不可能等于 $p_k$。
也就是说 $\ell(n)$ 就等于 $k-1$,即在上一轮就已经筛出了所有质数。此时终止递推。
后续 $k > \ell(n)$ 的 $G_k(n)$ 均等于 $G_{\ell(n)}(n)$。
:::
:::info[当 $p_k^2 \le n$ 时]{open}
此时 $G_k(n)$ 等于 $G_{k-1}(n)$ 减去这一轮被筛去的 $x$ 的 $g$ 值之和。
考虑 $m$ 的约束条件。
首先 $x = p_k \cdot m \le n$,即 $m \le n/p_k$。
由 $\operatorname{lpf}(m) \ge p_k$,显然有 $m \ge p_k$。
$\operatorname{lpf}(m) \ge p_k$ 即 $\operatorname{lpf}(m) > p_{k-1}$。
故 $m$ 满足:$p_k \le m \le n/p_k$ 且 $\operatorname{lpf}(m) > p_{k-1}$。
这些 $m$ 的 $g$ 值之和为 $\displaystyle\sum\limits_{\substack{m \in [p_k,n/p_k] \\ \operatorname{lpf}(m) > p_{k-1}}} g(m)$。
注意到 $G_{k-1}(n/p_k) = \displaystyle\sum\limits_{\substack{i \in [2,n/p_k] \\ \operatorname{lpf}(i) > p_{k-1} \lor \operatorname{isprime}(i)}} g(i)$。
考虑利用 $G_{k-1}(n/p_k)$ 统计 $m$ 的 $g$ 值之和。
我们发现,$G_{k-1}(n/p_k)$ 多统计了 $[2,p_k)$ 中的质数的 $g$ 值,即 $G_{\text{prime}}(p_{k-1})$。($[2,p_k)$ 中的质数即 $[2,p_{k-1}]$ 中的质数)
故这些 $m$ 的 $g$ 值之和为:
$$G_{k-1}(n/p_k) - G_{\text{prime}}(p_{k-1}).$$
由于 $g$ 是完全积性函数,故 $g(p_k \cdot m) = g(p_k)g(m)$。
故这一轮被筛去的 $x$ 的 $g$ 值之和为:
$$\begin{aligned}
\sum\limits_{\substack{m \in [p_k,n/p_k] \\ \operatorname{lpf}(m) > p_{k-1}}} g(p_k \cdot m) &= g(p_k) \sum\limits_{\substack{m \in [p_k,n/p_k] \\ \operatorname{lpf}(m) > p_{k-1}}} g(m)\\
&= g(p_k)\left( G_{k-1}(n/p_k) - G_{\text{prime}}(p_{k-1}) \right).
\end{aligned}$$
于是:
$$G_k(n) = G_{k-1}(n) - g(p_k)\left( G_{k-1}(n/p_k) - G_{\text{prime}}(p_{k-1}) \right).$$
:::
实现时,用两重循环分别枚举 $p_k$ 和可能的 $n'$。对于每一个 $n'$,从 $G_0(n')$ 推到 $G_{\ell(n')}(n')$ 即可得到 $G_{\text{prime}}(n')$。具体见代码。
其中 $g(p_k)$ 可以直接计算,$G_{\text{prime}}(p_{k-1})$ 可在线性筛时维护得出。
## 0x30 复杂度分析
对于 $F_k(n)$ 的计算,第一种方法的时间复杂度被证明为 $\Theta(n^{1 - \epsilon})$ $^{\textup{\textmd{\textsf{[1]}}}}$;第二种方法本质为洲阁筛的第二部分,其时间复杂度被证明为 $\mathcal{O}\left( \dfrac{n^\frac{3}{4}}{\log n} \right)$ $^{\textup{\textmd{\textsf{[2]}}}}$。
对于 $F_{\text{prime}}(n)$ 的计算,其实现与洲阁筛的第一部分相同。
考虑对于每个 $n' = n/i$,只有在枚举满足 $p_k^2 \le n'$ 的 $p_k$ 转移时会对复杂度产生贡献。则时间复杂度可估计为:
$$\begin{aligned}
T(n) &= \sum\limits_{i^2 \le n}\mathcal{O}\left( \pi \left( \sqrt{i}\right) \right) + \sum\limits_{i^2 \le n}\mathcal{O}\left( \pi \left( \sqrt{\frac{n}{i}} \right) \right)\\
&= \sum\limits_{i^2 \le n}\mathcal{O}\left( \frac{\sqrt{i}}{\ln \sqrt{i}} \right) + \sum\limits_{i^2 \le n}\mathcal{O}\left( \frac{\sqrt{\frac{n}{i}}}{\ln \sqrt{\frac{n}{i}}} \right)\\
&= \mathcal{O}\left( \int_{1}^{\sqrt{n}} \frac{\sqrt{\frac{n}{x}}}{\log \sqrt{\frac{n}{x}}} \mathrm{d}x\right)\\
&= \mathcal{O}\left( \dfrac{n^\frac{3}{4}}{\log n} \right).
\end{aligned}$$
空间复杂度显然为 $\Theta(\sqrt{n})$。
## 0x40 代码实现
本题中 $f(p) = p(p-1) = p^2 - p$。
我们需要分别维护 $g(p) = p$ 和 $g(p) = p^2$ 对应的 $G_{\text{prime}}$ 值与 $G_k$ 值。
令 $B \gets \lfloor \sqrt{n} \rfloor$。
首先预处理出 $\le B$ 的质数,同时维护这些质数的 $G_{\text{prime}}$ 值。其 $F_{\text{prime}}$ 值可由 $f$ 的每一项所对应的 $G_{\text{prime}}$ 值相加而得。
记 $s_i = G_{\text{prime}}(p_i)$。
然后进行一次数论分块,记录所有可能的 $n'$。设这些 $n'$ 中第 $i$ 大的为 $w_i$。
设 $w_i$ 的个数为 $\mathrm{tot}$。可以证明 $\mathrm{tot} \le 2\sqrt{n}$。
考虑如何通过 $n' = w_i$ 找到其编号 $i$。
对于 $n' = w_i \le B$,用数组 $\mathrm{id}_1$ 记录其编号 $i$,即 $\mathrm{id}_1(n') = i$。
对于 $n' = w_i > B$,用数组 $\mathrm{id}_2$ 记录其编号 $i$,即 $\mathrm{id}_2(n/n') = i$。($n/n' \in [1,B]$)
存储 $G_k(n')$ 时用 $n' = w_i$ 的编号 $i$ 作为索引。
对于每一个 $n'$,先算出 $G_0(n')$。
然后计算所有 $G_{\text{prime}}(n')$,即所有 $G_{\ell(n')}(n')$。
考虑两重循环,第一重循环枚举质数 $p_k$,第二重循环枚举 $n' = w_i$。按照递推式计算即可。注意在第二重循环时,由于 $w$ 数组单调递减,因此当 $p_k^2 > w_i$ 时,后面的 $w_{i+1}\sim w_{\mathrm{tot}}$ 均小于 $p_k^2$,此时应退出循环。
存储 $G_k(n)$ 的数组中 $k$ 这一维度可以滚动,甚至可以直接省去。由于 $w$ 数组单调递减,在计算 $G_k(n)$ 时 $G_k(n/p_k)$ 尚未被计算,若省去 $k$ 这一维度,此时数组中 $n/p_k$ 对应的位置存储的值恰为 $G_{k-1}(n/p_k)$。($G_{\ell(n/p_k)}(n/p_k)$ 亦等于 $G_{k-1}(n/p_k)$)
此时我们得到了所有 $G_{\text{prime}}(n')$,同时得到了所有 $F_{\text{prime}}(n')$。
最后,选用**第一种**计算 $F_k(n)$ 的方法递归计算 $F_1(n)$ 。
---
Code。
```cpp line-numbers
#include<bits/stdc++.h>
#define int long long
const int B=1e5+10;
const int TT=1e9+7;
using namespace std;
int n,b,ans;
int cnt,p[B];
bool vis[B];
int s1[B],s2[B]; // s1[i] 与 s2[i] 分别记录 g(p) = p 与 g(p) = p^2 的 G_prime(p[i])
int tot,w[B<<1]; // w[i] 为可能的 n',tot 为 w[i] 的个数
int id1[B],id2[B]; // id1[n] 与 id2[n/n'] 分别记录 n' = w[i] <= b 与 n' = w[i] > b 的编号 i
int g1[B<<1],g2[B<<1]; // g1[i] 与 g2[i] 分别记录 g(p) = p 与 g(p) = p^2 的 G_k(w[i]),最后得到的是它们的 G_prime(w[i])
int inv2,inv6;
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')ret=ret*10+(ch&15),ch=getchar();
return ret*f;
}
int _sqrt(int x){
int ret=floor(sqrtl(x));
while((ret+1)*(ret+1)<=x)ret++;
return ret;
}
int qpow(int x,int y){
x%=TT;
int ret=1;
while(y){
if(y&1)ret=ret*x%TT;
x=x*x%TT;
y>>=1;
}
return ret;
}
int get_id(int _n){ // n' 的编号
if(_n<=b)return id1[_n];
return id2[n/_n];
}
int _sub(int x,int y){ // 带取模的减法
return ((x-y)%TT+TT)%TT;
}
void _init(){
inv2=qpow(2,TT-2),inv6=qpow(6,TT-2); // 计算 2 和 6 的逆元
for(int i=2;i<=b;i++){
if(!vis[i]){
p[++cnt]=i;
s1[cnt]=(s1[cnt-1]+i)%TT; // 维护 g(p) = p 的 G_prime(p[i])
s2[cnt]=(s2[cnt-1]+i*i%TT)%TT; // 维护 g(p) = p^2 的 G_prime(p[i])
}
for(int j=1;j<=cnt&&i*p[j]<=b;j++){
vis[i*p[j]]=1;
if(!(i%p[j]))break;
}
}
for(int l=1,r;l<=n;l=r+1){ // 数论分块找到所有 n' 的可能值
r=n/(n/l);
int _n=n/l; // n' = n/l 为有效值
w[++tot]=_n; // 记录 w[i] = n'
if(_n<=b)id1[_n]=tot; // 记录 n' = w[i] 的编号
else id2[n/_n]=tot;
_n%=TT;
g1[tot]=_sub(_n*(_n+1)%TT*inv2%TT,1); // 计算 g(p) = p 的 G_0(w[i])
g2[tot]=_sub(_n*(_n+1)%TT*(_n*2+1)%TT*inv6%TT,1); // 计算 g(p) = p^2 的 G_0(w[i])
}
for(int k=1;k<=cnt;k++){ // 第一层循环枚举 p[k]
for(int i=1;i<=tot&&p[k]*p[k]<=w[i];i++){ // 第二层循环枚举 n' = w[i],p[k]*p[k] <= w[i] 作为循环条件之一
int id=get_id(w[i]/p[k]); // 找到 w[i]/p[k] 即 n'/p[k] 的编号
g1[i]=_sub(g1[i],p[k]*_sub(g1[id],s1[k-1])%TT); // g1[id]-s1[k-1] 即 G_{k-1}(n'/p[k]) - G_prime(p[k-1])
g2[i]=_sub(g2[i],p[k]*p[k]%TT*_sub(g2[id],s2[k-1])%TT); // 同上
}
}
}
int F(int k,int _n){ // 递归计算 F_k(n')
if(_n<p[k])return 0; // 若 n' < p[k],则 F_k(n) = 0
int id=get_id(_n); // 找到 n' 的编号
int ret=_sub(_sub(g2[id],g1[id]),_sub(s2[k-1],s1[k-1])); // 即 F_prime(n') - F_prime(p[k-1])
for(int i=k;i<=cnt&&p[i]*p[i]<=_n;i++){ // 枚举质数 p[i]
for(int _p=p[i];_p*p[i]<=_n;_p*=p[i]){ // 枚举 p[i] 的次数 c,_p 即 p[i]^c
int _p1=_p%TT,_p2=_p1*_p1%TT;
int _P1=_p*p[i]%TT,_P2=_P1*_P1%TT;
ret=(ret+_sub(_P2,_P1)+_sub(_p2,_p1)*F(i+1,_n/_p)%TT)%TT; // _P2 - _P1 即 f(p[i]^{c+1}),_p2 - _p1 即 f(p[i]^c)
}
}
return ret;
}
signed main(){
n=read();
b=_sqrt(n);
_init();
ans=(F(1,n)+1)%TT; // 答案为 F_1(n) + 1
printf("%lld\n",ans);
return 0;
}
```
## 0xFF 参考文献
本文还参考了一篇资料 $^{\textup{\textmd{\textsf{[3]}}}}$。
[1] 朱震霆. 一些特殊的数论函数求和问题[C]//张瑞喆. IOI2018 中国国家候选队论文集. 2018: 92-112.
[2] 任之洲. 积性函数求和的几种方法[C]//余林韵, 陈许旻. 2016 年信息学奥林匹克中国国家队候选队员论文集. 2016: 1-16.
[3] OI Wiki. Min_25 筛[DB/OL]. (2026-02-08)[2026-03-16]. https://oi-wiki.org/math/number-theory/min-25/.
---
**版权声明**:本文中 **0x00**、**0x10**、**0x20** 与 **0x30** 章节参考自 [OI Wiki](https://oi-wiki.org/),其内容在 **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.zh-hans)** 协议之条款下提供。本文亦采用 **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.zh-hans)** 协议发布。