整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无任何商业用途。因个人实力时间等原因,本文并非完全原创,请大家见谅。

目录

  • 《算法竞赛中的初等数论》(四)正文 0x40反演(ACM / OI / MO)(十五万字符数论书)
  • 0x40 反演
    • 0x41 整除分块
      • 0x41.1 前置知识
      • 0x41.2 整除分块
    • 0x42 莫比乌斯反演
      • 0x42.1 莫比乌斯反演公式
      • 0x42.2 莫比乌斯反演证明
      • 0x42.3 推导结论
      • 0x42.4 竞赛例题选讲
      • 0x42.5 莫比乌斯反演扩展
    • 0x43 欧拉反演
    • 0x44 二项式反演[^1]
    • 0x45 斯特林反演
    • 0x46 单位根反演
    • 0x47 子集反演
    • 0x48 最值反演 ( Min - Max 容斥)
    • 0x49 拉格朗日反演
    • 0x4A 反演常用技巧
    • 0x4B. Dirichlet 前缀和
      • 0x4B.1 Dirichlet 前缀和
      • 0x4B.2 Dirichlet 后缀和
      • 0x4B.2 倒推 Dirichlet 前缀和
      • 0x4B.3 倒推 Dirichlet 后缀和

《算法竞赛中的初等数论》(四)正文 0x40反演(ACM / OI / MO)(十五万字符数论书)

《算法竞赛中的初等数论》(信奥 / 数竞 / ACM)前言、后记、目录索引(十五万字符的数论书)

全文目录索引链接: https://fanfansann.blog.csdn.net/article/details/113765056


0x40 反演

0x41 整除分块

0x41.1 前置知识

引理 1

∀a,b,c∈Z,⌊abc⌋=⌊⌊ab⌋c⌋\forall a,b,c\in\mathbb{Z},\left\lfloor\frac{a}{bc}\right\rfloor=\left\lfloor\frac{\left\lfloor\frac{a}{b}\right\rfloor}{c}\right\rfloor ∀a,b,c∈Z,⌊bca​⌋=⌊c⌊ba​⌋​⌋

证明
ab=⌊ab⌋+r(0≤r<1)⟹⌊abc⌋=⌊ab⋅1c⌋=⌊1c(⌊ab⌋+r)⌋=⌊⌊ab⌋c+rc⌋=⌊⌊ab⌋c⌋□\begin{aligned} &\frac{a}{b}=\left\lfloor\frac{a}{b}\right\rfloor+r(0\leq r<1)\\ \implies &\left\lfloor\frac{a}{bc}\right\rfloor =\left\lfloor\frac{a}{b}\cdot\frac{1}{c}\right\rfloor =\left\lfloor \frac{1}{c}\left(\left\lfloor\frac{a}{b}\right\rfloor+r\right)\right\rfloor =\left\lfloor \frac{\left\lfloor\frac{a}{b}\right\rfloor}{c} +\frac{r}{c}\right\rfloor =\left\lfloor \frac{\left\lfloor\frac{a}{b}\right\rfloor}{c}\right\rfloor\\ &&\square \end{aligned} ⟹​ba​=⌊ba​⌋+r(0≤r<1)⌊bca​⌋=⌊ba​⋅c1​⌋=⌊c1​(⌊ba​⌋+r)⌋=⌊c⌊ba​⌋​+cr​⌋=⌊c⌊ba​⌋​⌋​□​

引理 2

∀n∈N+,∣{⌊nd⌋∣d∈N+,d≤n}∣≤⌊2n⌋\forall n \in \mathbb{N}_{+}, \left|\left\{ \left\lfloor \frac{n}{d} \right\rfloor \mid d \in \mathbb{N}_{+},d\leq n \right\}\right| \leq \left \lfloor 2\sqrt{n} \right\rfloor ∀n∈N+​,∣∣∣​{⌊dn​⌋∣d∈N+​,d≤n}∣∣∣​≤⌊2n​⌋

∣V∣|V|∣V∣ 表示集合 VVV 的元素个数

证明

对于 0≤d≤⌊n⌋0\le d\leq \left\lfloor\sqrt{n}\right\rfloor0≤d≤⌊n​⌋,显然一共最多只有 n\sqrt nn​ 种 ddd,显然 ⌊nd⌋\left\lfloor\dfrac{n}{d}\right\rfloor⌊dn​⌋ 有 ⌊n⌋\left\lfloor\sqrt{n}\right\rfloor⌊n​⌋ 种取值。

对于 d>⌊n⌋d> \left\lfloor\sqrt{n}\right\rfloord>⌊n​⌋,有0≤⌊nd⌋≤⌊n⌋0\le \left\lfloor\dfrac{n}{d}\right\rfloor\leq\left\lfloor\sqrt{n}\right\rfloor0≤⌊dn​⌋≤⌊n​⌋,显然也只有⌊n⌋\left\lfloor\sqrt{n}\right\rfloor⌊n​⌋ 种取值

综上,得证 □\ \square □

0x41.2 整除分块

  我们在计算 ∑i=1n⌊ni⌋\displaystyle \sum_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloori=1∑n​⌊in​⌋ 的时候,如果直接枚举的话,复杂度是 O(n)O(n)O(n) 的,在 nnn 很大的时候是很难计算的。但是当我们打表找规律的时候,发现序列 ⌊ni⌋\left\lfloor\dfrac{n}{i}\right\rfloor⌊in​⌋ 中有很多是相同的!(因为我们这里是下取整的形式,会丢掉所有小数),我们考虑对于元素相同的段 O(1)O(1)O(1) 计算,即求出该段的长度,然后乘上该段的值显然就是该段的和。

因此我们考虑对于含有 ⌊ni⌋\left\lfloor\dfrac{n}{i}\right\rfloor⌊in​⌋ 的求和式子(nnn 为给定的常数)

对于任意一个 i(i≤n)i(i\leq n)i(i≤n),我们需要找到一个最大的 j(i≤j≤n)j(i\leq j\leq n)j(i≤j≤n),使得 ⌊ni⌋=⌊nj⌋\left\lfloor\dfrac{n}{i}\right\rfloor = \left\lfloor\dfrac{n}{j}\right\rfloor⌊in​⌋=⌊jn​⌋,显然此时的 i,ji,ji,j 就是这段值相等的序列。

由引理1显然可以得到 j=⌊n⌊ni⌋⌋j=\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloorj=⌊⌊in​⌋n​⌋ (这里的除法都是下取整)

显然 j≤nj\leq nj≤n,考虑证明 j≥ij\geq ij≥i:

⌊ni⌋≤ni⟹⌊n⌊ni⌋⌋≥⌊nni⌋=⌊i⌋=i⟹i≤⌊n⌊ni⌋⌋=j□\begin{aligned} &\left\lfloor\frac{n}{i}\right\rfloor \leq \frac{n}{i}\\ \implies &\left\lfloor\frac{n}{ \left\lfloor\frac{n}{i}\right\rfloor }\right\rfloor \geq \left\lfloor\frac{n}{ \frac{n}{i} }\right\rfloor = \left\lfloor i \right\rfloor=i \\ \implies &i\leq \left\lfloor\frac{n}{ \left\lfloor\frac{n}{i}\right\rfloor }\right\rfloor=j\\ &&\square \end{aligned} ⟹⟹​⌊in​⌋≤in​⌊⌊in​⌋n​⌋≥⌊in​n​⌋=⌊i⌋=ii≤⌊⌊in​⌋n​⌋=j​□​

不妨设 k=⌊ni⌋k=\left\lfloor\dfrac{n}{i}\right\rfloork=⌊in​⌋,考虑证明当 ⌊nj⌋=k\left\lfloor\dfrac{n}{j}\right\rfloor=k⌊jn​⌋=k 时,jjj 的最大值为 ⌊nk⌋\left\lfloor\dfrac{n}{k}\right\rfloor⌊kn​⌋:

⌊nj⌋=k⟺k≤nj<k+1⟺1k+1<jn≤1k⟺nk+1<j≤nk\left\lfloor\frac{n}{j}\right\rfloor=k \iff k\leq\frac{n}{j}<k+1 \iff \frac{1}{k+1}<\frac{j}{n}\leq\frac{1}{k} \iff \frac{n}{k+1}<j\leq\dfrac{n}{k} ⌊jn​⌋=k⟺k≤jn​<k+1⟺k+11​<nj​≤k1​⟺k+1n​<j≤kn​

又因为 jjj 为整数 所以 jmax⁡=⌊nk⌋=⌊n⌊ni⌋⌋j_{\max}=\left\lfloor\dfrac{n}{k}\right\rfloor=\left\lfloor\dfrac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloorjmax​=⌊kn​⌋=⌊⌊in​⌋n​⌋

综上所诉,值相等的区间为 [i,j]=[i,⌊n⌊ni⌋⌋][i,j]=[i,\left\lfloor\dfrac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor][i,j]=[i,⌊⌊in​⌋n​⌋]

综上所述,我们每次以 [i,j][i,j][i,j] 为一块,分块求和即可。

Code

for(ll l = 1, r;l <= n; l = r + 1){r = n / (n / l);ans += (r - l + 1) * (n / l);
}

根据 引理2 ,显然该过程的时间复杂度为 O(n)O(\sqrt n)O(n​)


二维数论分块

∑i=1min⁡(n,m)⌊ni⌋⌊mi⌋\sum_{i=1}^{\min (n,m)}\left\lfloor\frac{n}{i} \right\rfloor\left\lfloor\frac{m}{i} \right\rfloor i=1∑min(n,m)​⌊in​⌋⌊im​⌋

每次右边界取 min⁡(⌊n⌊ni⌋⌋,⌊m⌊mi⌋⌋)\displaystyle \min(\left\lfloor\cfrac{n}{\lfloor \frac{n}{i}\rfloor}\right\rfloor,\left\lfloor\frac{m}{\lfloor \frac{m}{i}\rfloor}\right\rfloor)min(⌊⌊in​⌋n​⌋,⌊⌊im​⌋m​⌋),保证了两者分别相等,所以每两项的乘积相等。复杂度并没有变化。

Code

for(ll l = 1, r;l <= min(n, m); l = r + 1){r = min(n / (n / i), m / (m / i));ans += (r - l + 1) * (n / l) * (m / l);
}

Example A

计算

∑i=1ni⌊ni⌋\displaystyle \sum\limits_{i=1}^{n}i\left\lfloor\frac{n}{i}\right\rfloori=1∑n​i⌊in​⌋
Solution

对于每个块均有:

∑i=lri⌊ni⌋=∑i=lri⌊nl⌋=⌊nl⌋∑i=lri=⌊nl⌋×(r−l+1)(l+r)2\begin{aligned}\displaystyle \sum\limits_{i=l}^{r}i\left\lfloor \frac{n}{i}\right\rfloor&=\sum\limits_{i=l}^{r}i\left\lfloor \frac{n}{l}\right\rfloor&\\&=\left\lfloor \frac{n}{l}\right\rfloor\sum\limits_{i=l}^{r}i&\\&=\left\lfloor \frac{n}{l}\right\rfloor\times\frac{(r-l+1)(l+r)}{2}\end{aligned} i=l∑r​i⌊in​⌋​=i=l∑r​i⌊ln​⌋=⌊ln​⌋i=l∑r​i=⌊ln​⌋×2(r−l+1)(l+r)​​​

Example B

计算
∑i=1ni2⌊ni⌋\sum_{i=1}^{n}i^{2}\left \lfloor \frac{n}{i} \right \rfloor i=1∑n​i2⌊in​⌋
Solution

同样可以整除分块,只不过把等差数列求和公式换成平方数列求和的公式

Code

int cal(int x){return x * (x + 1) * (2 * x + 1) / 6;
}
int n, ans;
signed main(){cin >> n;for(int l = 1, r; l <= n; l = r + 1){r = n / (n / l);ans += (cal(r) - cal(l - 1)) * (n / l); }printf("%lld\n", ans);
}

Example C

计算
∑k=1n∑k∣xnx\sum^{n}_{k=1}\sum^{n}_{k|x}x k=1∑n​k∣x∑n​x
Solution

显然它的实际意义就是求 kkk 在 [1,n][1,n][1,n] 内的所有倍数和。

即对于每个 k,nk,nk,n 里会存在 ⌊nk⌋\left \lfloor \dfrac{n}{k} \right \rfloor⌊kn​⌋ 个 kkk 的倍数,而且是一个等差数列,公差为 kkk。所以式可以写成

∑k=1nk(⌊nk⌋+1)⌊nk⌋2\sum^{n}_{k=1}\frac{k(\left \lfloor \frac{n}{k} \right \rfloor+1)\left \lfloor \frac{n}{k} \right \rfloor}{2} k=1∑n​2k(⌊kn​⌋+1)⌊kn​⌋​

显然可以直接整除分块:

int n, ans1, ans2;
signed main(){cin >> n;for(int k = 1;k <= n; ++ k)for(int j = 1;j * k <= n; ++ j)ans1 += j * k;       for(int l = 1, r; l <= n; l = r + 1){r = n / (n / l);ans2 += (l + r) * (r - l + 1) / 2 * (1 + n / l) * (n / l) / 2;    }printf("%lld %lld\n", ans1, ans2);
}

Example E

计算
∑i=1n⌈ni⌉\displaystyle \sum\limits_{i=1}^{n}\left\lceil\frac{n}{i}\right\rceili=1∑n​⌈in​⌉

Solution

⌈ni⌉={⌊ni⌋i∣n⌊ni⌋+1i∤n\displaystyle \left\lceil\frac{n}{i}\right\rceil=\begin{cases}\left\lfloor\frac{n}{i}\right\rfloor&i\mid n\\\left\lfloor\frac{n}{i}\right\rfloor+1&i\nmid n\end{cases}⌈in​⌉={⌊in​⌋⌊in​⌋+1​i∣ni∤n​

一共有 d(n)d(n)d(n) (表示 nnn 的因数个数)个数满足 i∣ni\mid ni∣n ,我们计算全部都不能整除时的结果,最后减去因数个数。

∑i=1n⌈ni⌉=∑i=1n(⌊ni⌋+1)−d(n)=n−d(n)+∑i=1n⌊ni⌋\begin{aligned}\sum\limits_{i=1}^{n}\left\lceil\frac{n}{i}\right\rceil&=\sum\limits_{i=1}^{n}(\left\lfloor\frac{n}{i}\right\rfloor+1)-d(n)&\\&=n-d(n)+\sum\limits_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloor \end{aligned} i=1∑n​⌈in​⌉​=i=1∑n​(⌊in​⌋+1)−d(n)=n−d(n)+i=1∑n​⌊in​⌋​

Example F

计算

∑i=1n⌊ni2⌋\displaystyle \sum\limits_{i=1}^{n}\left\lfloor\cfrac{n}{i^2}\right\rfloori=1∑n​⌊i2n​⌋

Solution

令 l′=l2l'=l^2l′=l2 ,r′=r2r'=r^2r′=r2 ,由引理1可得 r′=⌊n⌊nl′⌋⌋\displaystyle r'=\left\lfloor\frac{n}{\lfloor \frac{n}{l'}\rfloor}\right\rfloorr′=⌊⌊l′n​⌋n​⌋ 。

r=⌊⌊n⌊nl2⌋⌋⌋\displaystyle r=\left\lfloor\sqrt{\left\lfloor\cfrac{n}{\left\lfloor \dfrac{n}{l^2}\right\rfloor}\right\rfloor}\right\rfloorr=⎣⎢⎢⎢⎢​⎣⎢⎢⎢​⌊l2n​⌋n​⎦⎥⎥⎥​​⎦⎥⎥⎥⎥​

Example G

已知 n,a,bn,a,bn,a,b 为正整数,求 ∑i=1n⌊nai+b⌋\displaystyle \sum\limits_{i=1}^{n}\left\lfloor\frac{n}{ai+b}\right\rfloori=1∑n​⌊ai+bn​⌋

Solution

令 l′=al+bl'=al+bl′=al+b , r′=ar+br'=ar+br′=ar+b ,由由引理1可得:

r′=⌊n⌊nl′⌋⌋\displaystyle r'=\left\lfloor\frac{n}{\left\lfloor \frac{n}{l'}\right\rfloor}\right\rfloorr′=⌊⌊l′n​⌋n​⌋

ar+b=⌊n⌊nl′⌋⌋\displaystyle ar+b=\left\lfloor\frac{n}{\left\lfloor \frac{n}{l'}\right\rfloor}\right\rfloorar+b=⌊⌊l′n​⌋n​⌋

r=⌊⌊n⌊nl′⌋⌋−ba⌋\displaystyle r=\left\lfloor\dfrac{\left\lfloor\dfrac{n}{\left\lfloor \frac{n}{l'}\right\rfloor}\right\rfloor-b}{a}\right\rfloorr=⎣⎢⎢⎢⎢⎢⎢⎢​a⌊⌊l′n​⌋n​⌋−b​⎦⎥⎥⎥⎥⎥⎥⎥​

Example H

一般地,对于和式: ∑i=1n⌊kf(i)⌋modp\displaystyle \sum\limits_{i=1}^{n}\left\lfloor\frac{k}{f(i)}\right\rfloor\bmod pi=1∑n​⌊f(i)k​⌋modp

其中 n,p,kn,p,kn,p,k 是正整数,1≤n≤10121\le n\le10^{12}1≤n≤1012,分块边界推导方法是:

⌊kf(l)⌋=⌊kf(r)⌋\displaystyle \left\lfloor \frac{k}{f(l)}\right\rfloor=\left\lfloor \frac{k}{f(r)}\right\rfloor⌊f(l)k​⌋=⌊f(r)k​⌋

引理1 可得

f(r)=⌊n⌊nf(l)⌋⌋f(r)=\left\lfloor\dfrac{n}{\left\lfloor\dfrac{n}{f(l)}\right\rfloor}\right\rfloorf(r)=⎣⎢⎢⎢⎢⎢​⌊f(l)n​⌋n​⎦⎥⎥⎥⎥⎥​

我们只需要求出 f(l)f(l)f(l) ,然后再解这个关于 rrr 的方程,最后向下取整,就得到了该块的右边界。

竞赛例题选讲

Problem A. 余数求和 (Luogu P2261[CQOI2007])

计算

ans=∑i=1n(kmodi)ans=\sum_{i=1}^n(k\bmod i)ans=i=1∑n​(kmodi)

Solution

显然有:

ans=∑i=1n(kmodi)=∑i=1nk−i⌊ki⌋ans=\sum_{i=1}^n(k\bmod i)=\sum_{i=1}^nk-i\left\lfloor\frac{k}{i}\right\rfloorans=i=1∑n​(kmodi)=i=1∑n​k−i⌊ik​⌋

整除分块即可。

Code

typedef long long ll;
const int N = 20007, M = 50007, INF = 0x3f3f3f3f;
ll n, k;
int main()
{scanf("%lld%lld", &n, &k);ll ans = n * k; for(ll l = 1, r; l <= n; l = r + 1){if(k / l != 0)r = min((k / (k / l)) , n);else r = n;ans -= (r + l) * (k / l) * (r - l + 1) / 2;//先乘后除,因为中间除2可能不能整除//区间内i的平均值 * (k / l) * 区间长度}printf("%lld\n", ans);return 0;
}

Problem B 小G的约数(牛客练习赛77C)

  小G定义了两个函数 F(n)F(n)F(n) 为 nnn 的约数和,G(n)G(n)G(n) 为 F(1)+F(2)+...+F(n−1)+F(n)F(1)+F(2)+...+F(n-1)+F(n)F(1)+F(2)+...+F(n−1)+F(n)

小G想知道 G(G(n))G(G(n))G(G(n)) 等于多少。

n≤5×104n\le 5\times 10^4n≤5×104

Solution

我们知道对于 i∈[1,n]i\in[1,n]i∈[1,n],约数为 iii 的整数的个数为 ⌊ni⌋\left\lfloor\dfrac{n}{i}\right\rfloor⌊in​⌋
显然 1∼n1\sim n1∼n 的约数和为:

G(n)=∑i=1n⌊ni⌋×iG(n)=\sum_{i=1}^n \left\lfloor\cfrac{n}{i}\right\rfloor\times iG(n)=i=1∑n​⌊in​⌋×i

显然前面的 ⌊ni⌋\left\lfloor\dfrac{n}{i}\right\rfloor⌊in​⌋ 可以直接整除分块,后面的 iii 相当于对于区间 [l,r][l,r][l,r], ⌊ni⌋×(l+(l+1)+⋯+(r−1)+r)=⌊ni⌋×l+r2\left\lfloor\dfrac{n}{i}\right\rfloor\times (l+(l+1)+\cdots+(r-1)+r)= \left\lfloor\dfrac{n}{i}\right\rfloor\times \cfrac{l+r}{2}⌊in​⌋×(l+(l+1)+⋯+(r−1)+r)=⌊in​⌋×2l+r​ ,O(n)O(\sqrt{n})O(n​) 的复杂度实现。

Code

#define int long long
const int N = 5e5 + 7, mod = 1e9 + 7;
const double PI = acos(-1.0);int n, m;int G(int n)
{int res = 0;for(int l = 1, r; l <= n; l = r + 1) {r = n / (n / l);res += (r - l + 1) * (l + r) / 2 * (n / l);}return res;
}signed main()
{scanf("%lld", &n);printf("%lld\n", G(G(n)));return 0;
}

Problem C. Dividing(2020牛客多校 7 - H)

在1≤n≤N,1≤k≤K1\leq n \leq N,1\le k\le K1≤n≤N,1≤k≤K 范围内,有多少对(n,k)(n,k)(n,k) 是传奇对。传奇对的条件是:

(1,k)(1,k)(1,k) 一定是传奇对;
若 (n,k)(n,k)(n,k) 是传奇对,(n+k,k)(n+k,k)(n+k,k) 和 (nk,k)(nk,k)(nk,k) 都是传奇对。

Solution
%https://blog.csdn.net/weixin_45630722/article/details/107772230

%https://blog.csdn.net/Luowaterbi/article/details/107733386

Problem D. Floor and Mod (CF1485C Floor and Mod)

Translation

定义一对数 (a,b)(a,b)(a,b) 是特殊的,当且仅当 ⌊ab⌋=amodb\left\lfloor\dfrac{a}{b}\right\rfloor=a\mod b⌊ba​⌋=amodb

给定 xxx 和 yyy ,求一共有多少对特殊的数 (a,b)(a,b)(a,b) ,当 1≤a≤x,1≤b≤y1\le a\le x,1\le b\le y1≤a≤x,1≤b≤y。

Solution

显然是一个结论题或者枚举题,我们根据题目中给定的柿子:

⌊ab⌋=amodb⌊ab⌋=a−⌊ab⌋×ba=⌊ab⌋×(b+1)ab+1=⌊ab⌋\begin{aligned}&\left\lfloor\cfrac{a}{b}\right\rfloor=a\mod b &\\& \left \lfloor\cfrac{a}{b}\right\rfloor=a-\left\lfloor\cfrac{a}{b}\right\rfloor\times b&\\& a=\left\lfloor\cfrac{a}{b}\right\rfloor\times (b+1)&\\& \cfrac{a}{b+1}=\left\lfloor\cfrac{a}{b}\right\rfloor\end{aligned} ​⌊ba​⌋=amodb⌊ba​⌋=a−⌊ba​⌋×ba=⌊ba​⌋×(b+1)b+1a​=⌊ba​⌋​​

因为⌊ab⌋\left\lfloor\dfrac{a}{b}\right\rfloor⌊ba​⌋ 一定是整数,所以 ab+1\cfrac{a}{b+1}b+1a​ 一定是整数,所以 b+1∣ab+1\ |\ ab+1 ∣ a。

所以一个很直观的想法就是枚举 bbb ,对于每一个 bbb , b+1b+1b+1 的倍数 aaa 显然有 xb+1\cfrac{x}{b+1}b+1x​ 个,显然可以整除分块。

但是需要注意题目中的给定的条件为 ⌊ab⌋=amodb\left\lfloor\dfrac{a}{b}\right\rfloor=a\mod b⌊ba​⌋=amodb

即: ⌊ab⌋<b\left\lfloor\dfrac{a}{b}\right\rfloor<b⌊ba​⌋<b

即:ab+1<b⇒a<b2+b\cfrac{a}{b+1}<b\Rightarrow a<b^2+bb+1a​<b⇒a<b2+b

即 a∈[0,b2+b−1]a\in [0,b^2+b-1]a∈[0,b2+b−1]。那么符合题意的 aaa 的个数就是: b2+b−1b+1\cfrac { b^2+b-1}{b+1}b+1b2+b−1​

并且 aaa 的上限是 xxx,故最终的答案为:

∑b=1yans=min⁡{x,b2+b−1}b+1\sum\limits_{b=1}^{y} ans = \cfrac {\min\{x, b^2+b-1\}}{b+1}b=1∑y​ans=b+1min{x,b2+b−1}​

我们可以先枚举 b<xb<\sqrt xb<x​ ,计算 b2+b−1b+1\cfrac { b^2+b-1}{b+1}b+1b2+b−1​

剩余的 b=x∼yb=\sqrt x \sim yb=x​∼y,显然 min⁡{x,b2+b−1}=x{\min\{x, b^2+b-1\}}=xmin{x,b2+b−1}=x,直接整除分块即可,其中整除分块的时候,我们需要计算的是 ⌊xb+1⌋\left\lfloor \dfrac{x}{b+1}\right\rfloor⌊b+1x​⌋,我们令 l,rl,rl,r 代表 b+1b+1b+1 即可。

时间复杂度 O(x)O(\sqrt x)O(x​)

Code

using ll = long long;
const int N = 1e5 + 7;int n, m, t;
int x, y;int main()
{scanf("%d", &t);while(t -- ) {scanf("%d%d", &x, &y);int a = 1, b = 1;ll ans = 0;for(; b * b + b - 1 < x && b <= y; ++ b) ans += (b * b + b - 1) / (b + 1);       int l = b + 1, r;  for(; l <= x && l <= y + 1; l = r + 1) {r = min(x / (x / l), y + 1);ans += x / l * (r - l + 1); if(r == y + 1) break;} cout << ans << endl;}     return 0;
}

0x42 莫比乌斯反演

莫比乌斯函数

莫比乌斯函数已在 0x30 积性函数 一章做过详细讲解和性质证明,这里罗略一些常用的性质,在讲解莫比乌斯反演的时候将会用到它们。

定义

μ(n)={0∃i∈[1,m],Ci>1(−1)m∀i∈[1,m],Ci=1\mu(n) = \left\{ \begin{matrix} 0 & \exists i \in [1,m],C_i>1 \\ (-1)^m & \forall i \in [1,m],C_i=1 \end{matrix} \right.μ(n)={0(−1)m​∃i∈[1,m],Ci​>1∀i∈[1,m],Ci​=1​

  • 基本性质定理

性质32.1:

∑d∣nμ(d)={1n=10n≠1\sum_{d\mid n}\mu(d)= \begin{cases} 1&n=1\\ 0&n\neq 1\\ \end{cases} d∣n∑​μ(d)={10​n=1n​=1​

即 ∑d∣nμ(d)=ε(n)\sum_{d\mid n}\mu(d)=\varepsilon(n)∑d∣n​μ(d)=ε(n),μ∗1=ε\mu * 1 =\varepsilonμ∗1=ε,其中 ∗*∗ 是指 DirichletDirichletDirichlet 卷积。

性质32.2:

[gcd⁡(i,j)=1]=∑d∣gcd⁡(i,j)μ(d)\displaystyle [\gcd(i,j)=1]=\sum_{d\mid\gcd(i,j)}\mu(d)[gcd(i,j)=1]=d∣gcd(i,j)∑​μ(d)

0x42.1 莫比乌斯反演公式

设 F(n),f(n)F(n),f(n)F(n),f(n) 为两个数论函数。

形式一:

如果有 F(n)=∑d∣nf(d)\displaystyle F(n)=\sum_{d\mid n}f(d)F(n)=d∣n∑​f(d),那么有 f(n)=∑d∣nμ(d)F(nd)\displaystyle f(n)=\sum_{d\mid n}\mu(d)F(\cfrac{n}{d})f(n)=d∣n∑​μ(d)F(dn​)。

形式二:

如果有 F(n)=∑n∣df(d)\displaystyle F(n)=\sum_{n|d}f(d)F(n)=n∣d∑​f(d),那么有 f(n)=∑n∣dμ(dn)F(d)\displaystyle f(n)=\sum_{n|d}\mu(\cfrac{d}{n})F(d)f(n)=n∣d∑​μ(nd​)F(d)。

一般在求解数论函数 fff 无法直接求解的时候,就可以构造 F(n)=∑d∣nf(d)\displaystyle F(n)=\sum\limits_{d\mid n}^{}f(d)F(n)=d∣n∑​f(d) 或 F(n)=∑n∣df(d)\displaystyle F(n)=\sum_{n|d}f(d)F(n)=n∣d∑​f(d),求出更好求解的 F(n)F(n)F(n) ,此时利用枚举倍数的技巧在 O(nlog⁡n)O(n\log n)O(nlogn) 的复杂度下利用反演公式求解出待求的 fff 即可。

0x42.2 莫比乌斯反演证明

建议掌握反演的证明,因为我们在写莫比乌斯反演题目的时候,大多数都是直接推式子而不是使用反演公式。

形式一证明

证明一: 对原式做数论变换。

∑d∣nμ(d)F(nd)=∑d∣nμ(d)∑k∣ndf(k)=∑k∣nf(k)∑d∣nkμ(d)=f(n)\begin{aligned}\sum_{d\mid n}\mu(d)F(\frac{n}{d})&=\sum_{d\mid n}\mu(d)\sum_{k\mid \frac{n}{d}}f(k)&\\&=\sum_{k\mid n}f(k)\sum_{d\mid \frac{n}{k}}\mu(d)&\\&=f(n)\end{aligned} d∣n∑​μ(d)F(dn​)​=d∣n∑​μ(d)k∣dn​∑​f(k)=k∣n∑​f(k)d∣kn​∑​μ(d)=f(n)​​

解释: 根据定义 F(n)=∑d∣nf(d)\displaystyle F(n)=\sum_{d\mid n}f(d)F(n)=d∣n∑​f(d) ,我们使用 ∑d∣nf(d)\displaystyle\sum_{d\mid n}f(d)d∣n∑​f(d) 来替换 F(nd)F(\cfrac{n}{d})F(dn​),再交换求和顺序(nd\dfrac n ddn​ 意味着 nnn 的所有因子,k∣ndk\mid \dfrac n dk∣dn​ 则 kkk 也是 nnn 的所有因子,即单独枚举 k∣nk\mid nk∣n,此时d∣n=d∣nkd\mid n=d\mid \cfrac n kd∣n=d∣kn​,我们可以将 d∣nd\mid nd∣n 换成 nk\cfrac n kkn​ ,是完全等价的)。最后根据莫比乌斯函数的 性质32.1 :∑d∣nμ(d)=[n=1]\displaystyle\sum_{d\mid n}\mu(d)=[n=1]d∣n∑​μ(d)=[n=1],因此在 nk=1\dfrac{n}{k}=1kn​=1 时第二个和式的值才为 111,否则全是 000 。此时 n=kn=kn=k,故原式等价于
∑k∣n[n=k]⋅f(k)=f(n)\displaystyle\sum_{k\mid n}[n=k]\cdot f(k)=f(n)k∣n∑​[n=k]⋅f(k)=f(n)
反演公式得证 □\ \square □

证明二: 利用 Dirichlet\text{Dirichlet}Dirichlet 卷积。

反演公式

设 F(n),f(n)F(n),f(n)F(n),f(n) 为两个数论函数。

如果有 F(n)=∑d∣nf(d)\displaystyle F(n)=\sum_{d\mid n}f(d)F(n)=d∣n∑​f(d),那么有 f(n)=∑d∣nμ(d)F(nd)\displaystyle f(n)=\sum_{d\mid n}\mu(d)F(\cfrac{n}{d})f(n)=d∣n∑​μ(d)F(dn​)。

显然可以转化为 Dirichlet\text{Dirichlet}Dirichlet 卷积下的 ,已知 F=f∗1F=f\ast1F=f∗1,证明 f=F∗μf=F\ast\muf=F∗μ

显然有:

F∗μ=f∗1∗μ=f∗ε(1∗μ=ε,ε∗f=f)=f\begin{aligned}F\ast\mu&=f*1*\mu &\\&= f*\varepsilon\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ( 1\ast\mu=\varepsilon,\varepsilon*f=f) &\\&= f \end{aligned} F∗μ​=f∗1∗μ=f∗ε                (1∗μ=ε,ε∗f=f)=f​​
反演公式得证 □\ \square □


形式二证明

证明一: 我们考虑逆推这个式子。

∑n∣dμ(dn)F(d)=∑k=1+∞μ(k)F(kn)=∑k=1+∞μ(k)∑kn∣df(d)=∑n∣df(d)∑k∣dnμ(k)=∑n∣df(d)ϵ(dn)=∑n∣df(d)[dn=1]=∑n∣df(d)[n=d]=f(n)\begin{aligned} \sum_{n|d}{\mu(\frac{d}{n})F(d)} &= \sum_{k=1}^{+\infty}{\mu(k)F(kn)}&\\& = \sum_{k=1}^{+\infty}{\mu(k)\sum_{kn|d}{f(d)}}&\\& = \sum_{n|d}{f(d)\sum_{k|\frac{d}{n}}{\mu(k)}}&\\& = \sum_{n|d}{f(d)\epsilon(\frac{d}{n})}&\\& = \sum_{n|d}{f(d)[\frac{d}{n}=1]}&\\& = \sum_{n|d}{f(d)[n=d]}&\\& = f(n) \end{aligned} n∣d∑​μ(nd​)F(d)​=k=1∑+∞​μ(k)F(kn)=k=1∑+∞​μ(k)kn∣d∑​f(d)=n∣d∑​f(d)k∣nd​∑​μ(k)=n∣d∑​f(d)ϵ(nd​)=n∣d∑​f(d)[nd​=1]=n∣d∑​f(d)[n=d]=f(n)​​

我们把 ddd 表示为 knknkn 的形式,然后把 F(n)=∑n∣df(d)\displaystyle F(n)=\sum_{n\mid d}f(d)F(n)=n∣d∑​f(d) 代入式子。

发现枚举 kkk 再枚举 knknkn 的倍数可以转换为直接枚举 nnn 的倍数再求出 kkk,发现后面那一块其实就是 ϵ\epsilonϵ,式子只有在 d=nd=nd=n 的时候才不为 000。


0x42.3 推导结论

一些常用结论

(1)GCD与LCM

结论42.1.1: [gcd⁡(i,j)=1]=∑d∣i,d∣jμ(d)\displaystyle [\gcd(i,j)=1]=\sum_{d|i,d|j} \mu(d)[gcd(i,j)=1]=d∣i,d∣j∑​μ(d)

结论42.1.2:∑i=1n∑i=1m[gcd⁡(i,j)=k]=\displaystyle \sum_{i=1}^{n}\sum_{i=1}^{m}[\gcd(i,j)=k]=i=1∑n​i=1∑m​[gcd(i,j)=k]=∑d=1⌊nk⌋μ(d)⌊ndk⌋⌊mdk⌋\sum_{d=1}^{\lfloor\frac{n}{k}\rfloor} \mu(d)\lfloor\dfrac{n}{d k}\rfloor\lfloor\dfrac{m}{d k}\rfloor∑d=1⌊kn​⌋​μ(d)⌊dkn​⌋⌊dkm​⌋(例题)

结论42.1.3:∑i=1n∑i=1m[gcd⁡(i,j)∈{Prime}]=\displaystyle \sum_{i=1}^{n}\sum_{i=1}^{m}[\gcd(i,j)\in \{\text{Prime}\}]=i=1∑n​i=1∑m​[gcd(i,j)∈{Prime}]=∑d=1n(⌊nd⌋⌊md⌋∑p∣d&p∈{Prime}μ(dp))\sum_{d=1}^{n}\left(\lfloor\dfrac{n}{d}\rfloor\lfloor\dfrac{m}{d}\rfloor\sum_{p | d\ \&\ p\in\{Prime\}} \mu(\dfrac{d}{p})\right)∑d=1n​(⌊dn​⌋⌊dm​⌋∑p∣d & p∈{Prime}​μ(pd​))(例题)

结论42.1.4:∑i=1n∑j=1mlcm⁡(i,j)=\displaystyle \sum_{i=1}^{n} \sum_{j=1}^{m} \operatorname{lcm}(i,j)=i=1∑n​j=1∑m​lcm(i,j)=∑d=1nd(∑x=1⌊nd⌋x2μ(x)∑i=1⌊ndx⌋i∑i=1⌊mdx⌋j)\sum_{d=1}^{n} d\left(\sum_{x=1}^{\lfloor\frac{n}{d}\rfloor} x^{2} \mu(x) \sum_{i=1}^{\lfloor\frac{n}{dx}\rfloor} i\sum_{i=1}^{\lfloor\frac{m}{dx}\rfloor} j \right)∑d=1n​d(∑x=1⌊dn​⌋​x2μ(x)∑i=1⌊dxn​⌋​i∑i=1⌊dxm​⌋​j)(例题)

(2)除数函数

结论42.2.1:σk=∑d∣nidk\displaystyle \sigma_{k}=\sum_{d|n}id^{k}σk​=d∣n∑​idk,即σk=id⁡k∗1\sigma_{k}=\operatorname{id}_{k}\ast1σk​=idk​∗1

σ0(x)\sigma_0(x)σ0​(x) 表示 xxx 的约数个数

结论42.2.2:σ0(xy)=∑i∣x∑j∣y[gcd⁡(i,j)=1]\displaystyle \sigma_0(xy)=\sum_{i|x} \sum_{j|y}[\operatorname{gcd}(i,j)=1]σ0​(xy)=i∣x∑​j∣y∑​[gcd(i,j)=1]

结论42.2.3:∑i=1nσ0(i)=\displaystyle \sum_{i=1}^{n}\sigma_0(i)=i=1∑n​σ0​(i)=(例题)

结论42.2.4:∑i=1n∑j=1mσ0(ij)=\displaystyle \sum_{i=1}^{n} \sum_{j=1}^{m} \sigma_0(ij)=i=1∑n​j=1∑m​σ0​(ij)=∑k=1nμ(k)(∑i=1⌊nk⌋⌊nik⌋)(∑i=1⌊mk⌋⌊mik⌋)\sum_{k=1}^{n}\mu(k)\left(\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\lfloor{\dfrac{n}{ik}}\rfloor\right)\left(\sum_{i=1}^{\lfloor\frac{m}{k}\rfloor}\lfloor\dfrac{m}{i k}\rfloor\right)∑k=1n​μ(k)(∑i=1⌊kn​⌋​⌊ikn​⌋)(∑i=1⌊km​⌋​⌊ikm​⌋)(例题)

σ1(x)\sigma_1(x)σ1​(x) 表示 xxx 的约数和

结论42.2.5:d(xy)=∑i∣x∑j∣yiyj[gcd⁡(i,j)=1]\displaystyle d(xy)=\sum_{i\mid x}\sum_{j\mid y} \frac{iy}{j}[\gcd(i,j)=1]d(xy)=i∣x∑​j∣y∑​jiy​[gcd(i,j)=1]

结论42.2.6:∑i=1n∑j=1nσ1(ij)=\displaystyle \sum_{i=1}^{n}\sum_{j=1}^{n}\sigma_1(ij)=i=1∑n​j=1∑n​σ1​(ij)=∑d=1nμ(d)d(∑i=1⌊nd⌋σ1(i))2\sum_{d=1}^{n}\mu(d)d \left(\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor} \sigma_1(i)\right)^{2}∑d=1n​μ(d)d(∑i=1⌊dn​⌋​σ1​(i))2(例题)

结论42.2.7:∑i=1n∑j=1mσ1(gcd⁡(i,j))=\displaystyle \sum_{i=1}^{n}\sum_{j=1}^{m} \sigma_1(\gcd(i,j))=i=1∑n​j=1∑m​σ1​(gcd(i,j))=∑d=1n⌊nd⌋⌊md⌋(∑i∣dμ(di)σ1(i))\sum_{d=1}^{n}\lfloor\dfrac{n}{d}\rfloor\lfloor\dfrac{m}{d}\rfloor\left(\sum_{i\mid d}\mu(\dfrac{d}{i}) \sigma_1(i)\right)∑d=1n​⌊dn​⌋⌊dm​⌋(∑i∣d​μ(id​)σ1​(i))(例题)

(3)莫比乌斯函数

结论42.3.1:∑k=1nμ2(k)=∑d=1nμ(d)⌊nd2⌋\displaystyle \sum_{k=1}^{n}\mu^{2}(k)=\sum_{d=1}^{\sqrt{n}}\mu(d)\lfloor \frac{n}{d^{2}}\rfloork=1∑n​μ2(k)=d=1∑n​​μ(d)⌊d2n​⌋(例题)

结论42.3.2:∑i=1nμ2(i)ni=n\displaystyle \sum_{i=1}^{n}\mu^2(i)\sqrt{\frac{n}{i}}=ni=1∑n​μ2(i)in​​=n(例题)


0x42.4 竞赛例题选讲

Problem A. problem b(P2522 [HAOI2011])

对于给出的 nnn 个询问,每次求有多少个数对 (x,y)(x,y)(x,y),满足 a≤x≤ba \le x \le ba≤x≤b ,c≤y≤dc \le y \le dc≤y≤d,且 gcd⁡(x,y)=k\gcd(x,y) = kgcd(x,y)=k,gcd⁡(x,y)\gcd(x,y)gcd(x,y) 函数为 xxx 和 yyy 的最大公约数。

1≤n,k≤5×1041 \le n,k \le 5 \times 10^41≤n,k≤5×104 ,1≤a≤b≤5×1041 \le a \le b \le 5 \times 10^41≤a≤b≤5×104, 1≤c≤d≤5×1041 \le c \le d \le 5 \times 10^41≤c≤d≤5×104

Solution

方法一:直接推导公式

显然问题可以抽象成等式:
∑i=ab∑j=cd[gcd⁡(i,j)=k]\sum_{i=a}^{b}\sum_{j=c}^{d}[\gcd(i,j)=k]\qquad i=a∑b​j=c∑d​[gcd(i,j)=k]

枚举的范围从 a,ca,ca,c 出发,不好处理,我们考虑转换成从 111 出发的形式。

根据容斥原理,原式可以分成 444 块来处理:

ans=solve(1∼b,1∼d)−solve(1∼a−1,1∼d)−solve(1∼b,1∼c−1)+solve(1∼a−1,1∼c−1)ans=\text{solve}(1\sim b,1\sim d)-\text{solve}(1\sim a-1,1\sim d)-\text{solve}(1\sim b,1\sim c-1)+\text{solve}(1\sim a-1,1\sim c-1)ans=solve(1∼b,1∼d)−solve(1∼a−1,1∼d)−solve(1∼b,1∼c−1)+solve(1∼a−1,1∼c−1)

(减去一个不合法的部分,加上两个都不合法的部分)

其中 solve\text{solve}solve 中要处理的式子都为:
∑i=1n∑j=1m[gcd⁡(i,j)=k]=∑i=1n∑j=1m[gcd⁡(ik,jk)=1]只有k的倍数才有贡献,而[1,n]中k的倍数显然有⌊nk⌋个所以令i=ik即仅枚举k的倍数即可=∑i=1⌊nk⌋∑j=1⌊mk⌋[gcd⁡(i,j)=1](所有k的倍数,除去k后互质才有贡献)=∑i=1⌊nk⌋∑j=1⌊mk⌋ε(gcd⁡(i,j))=∑i=1⌊nk⌋∑j=1⌊mk⌋∑d∣gcd⁡(i,j)μ(d)=∑d=1min⁡{⌊nk⌋,⌊mk⌋}μ(d)∑i=1⌊nk⌋[d∣i]∑j=1⌊mk⌋[d∣j]=∑d=1min⁡{⌊nk⌋,⌊mk⌋}}μ(d)⌊nkd⌋⌊mkd⌋\begin{aligned} \sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=k] &=\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(\frac i k,\frac j k) =1]\ &\\&只有 k 的倍数才有贡献,而[1,n]中k的倍数显然有\left\lfloor\frac{n}{k}\right\rfloor 个&\\&所以令\ i=ik\ 即仅枚举k的倍数即可 &\\&=\sum_{i=1}^{\left\lfloor\frac{n}{k}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{k}\right\rfloor}[\gcd(i,j)=1]&\\&(所有k的倍数,除去k后互质才有贡献) &\\&=\sum_{i=1}^{\left\lfloor\frac{n}{k}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{k}\right\rfloor}\varepsilon(\gcd(i,j)) &\\&=\displaystyle\sum_{i=1}^{\left\lfloor\frac{n}{k}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{k}\right\rfloor}\sum_{d\mid \gcd(i,j)}\mu(d) &\\&=\displaystyle\sum_{d=1}^{\min\{\left\lfloor\frac n k\right\rfloor,\left\lfloor\frac m k\right\rfloor\}}\mu(d)\sum_{i=1}^{\left\lfloor\frac{n}{k}\right\rfloor}[d\mid i]\sum_{j=1}^{\left\lfloor\frac{m}{k}\right\rfloor}[d\mid j] &\\&=\displaystyle\sum_{d=1}^{\min\{\left\lfloor\frac n k\right\rfloor,\left\lfloor\frac m k\right\rfloor\}\}}\mu(d)\left \lfloor\frac{n}{kd}\right\rfloor\left\lfloor\frac{m}{kd}\right\rfloor \end{aligned} i=1∑n​j=1∑m​[gcd(i,j)=k]​=i=1∑n​j=1∑m​[gcd(ki​,kj​)=1] 只有k的倍数才有贡献,而[1,n]中k的倍数显然有⌊kn​⌋个所以令 i=ik 即仅枚举k的倍数即可=i=1∑⌊kn​⌋​j=1∑⌊km​⌋​[gcd(i,j)=1](所有k的倍数,除去k后互质才有贡献)=i=1∑⌊kn​⌋​j=1∑⌊km​⌋​ε(gcd(i,j))=i=1∑⌊kn​⌋​j=1∑⌊km​⌋​d∣gcd(i,j)∑​μ(d)=d=1∑min{⌊kn​⌋,⌊km​⌋}​μ(d)i=1∑⌊kn​⌋​[d∣i]j=1∑⌊km​⌋​[d∣j]=d=1∑min{⌊kn​⌋,⌊km​⌋}}​μ(d)⌊kdn​⌋⌊kdm​⌋​​

显然可以整除分块,时间复杂度为 O(N+Tn)O(N+T\sqrt n)O(N+Tn​)

方法二:利用反演公式:

Code

const int N = 500007, M = 500007,INF = 0x3f3f3f3f;
typedef long long ll;
int read()
{int x = 0, f = 1;char ch = getchar();while(ch > '9' || ch < '0'){if(ch == '-')f = -1; ch = getchar();}while(ch <= '9' && ch >= '0'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}
int a, b, c, d, k;
int mu[N];
int primes[N], cnt;
bool vis[N];void get_mu(int n)
{memset(vis, 0, sizeof vis);memset(mu, 0, sizeof mu);cnt = 0, mu[1] = 1;for(int i = 2; i <= n; ++ i){if(vis[i] == 0){primes[ ++ cnt] = i;mu[i] = -1;}for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j){vis[primes[j] * i] = 1;if(i % primes[j] == 0) break;mu[i * primes[j]] -= mu[i];}}for(int i = 1; i <= n; ++ i)mu[i] += mu[i - 1];
}int solve(int n, int m)
{n /= k, m /= k;int res = 0;for(int i = 1, j; i <= min(n, m); i = j + 1){j = min(n / (n / i), m / ( m / i));//j是右边界,这里的值都是ires += (mu[j] - mu[i - 1]) * (n / i) * (m / i);}return res;
}
int n, m;int main()
{get_mu(N - 1);scanf("%d", &n);for(int i = 1; i <= n; ++ i){a = read(), b = read(), c = read(), d = read(), k = read();int ans = solve(b, d) - solve(b, c - 1) - solve(a - 1, d) + solve(a - 1, c - 1);printf("%d\n", ans);}return 0;
}

Problem B. LCMSUM (Luogu SP5971)

计算

∑i=1nlcm⁡(i,n)\sum_{i=1}^n \operatorname{lcm}(i,n) i=1∑n​lcm(i,n)

多组数据

1⩽T⩽3×105,1⩽n⩽106\ 1\leqslant T\leqslant 3\times 10^5,1\leqslant n\leqslant 10^6 1⩽T⩽3×105,1⩽n⩽106

Solution

方法一:

ans=∑i=1nlcm⁡(i,n)=∑i=1ni⋅ngcd⁡(i,n)=n×∑i=1nigcd⁡(i,n)=n×∑d∣n∑i=1nid[gcd⁡(i,n)=d]=n×∑d∣n∑i=1nid[gcd⁡(id,nd)]=n×∑d∣n∑i=1⌊nd⌋i⋅[gcd⁡(i,nd)](i=id)\begin{aligned}ans&=\sum_{i=1}^n \operatorname{lcm}(i,n)&\\&=\sum_{i=1}^n \frac{i\cdot n}{\gcd(i,n)} &\\&=n\times \sum_{i=1}^n \frac{i }{\gcd(i,n)} &\\&=n\times \sum_{d\mid n}\sum_{i=1}^n \frac{i }{d}[\gcd(i,n)=d] &\\&=n\times \sum_{d\mid n}\sum_{i=1}^n \frac{i }{d}[\gcd(\frac i d,\frac n d)] &\\&=n\times \sum_{d\mid n}\sum_{i=1}^{ \lfloor\frac n d \rfloor} i\cdot [\gcd(i,\frac n d)]&(i=id) \end{aligned} ans​=i=1∑n​lcm(i,n)=i=1∑n​gcd(i,n)i⋅n​=n×i=1∑n​gcd(i,n)i​=n×d∣n∑​i=1∑n​di​[gcd(i,n)=d]=n×d∣n∑​i=1∑n​di​[gcd(di​,dn​)]=n×d∣n∑​i=1∑⌊dn​⌋​i⋅[gcd(i,dn​)]​(i=id)​

设 f(n)=∑i=1⌊nd⌋i⋅[gcd⁡(i,nd)]\displaystyle f(n)= \sum_{i=1}^{ \lfloor\frac n d \rfloor} i\cdot [\gcd(i,\frac n d)]f(n)=i=1∑⌊dn​⌋​i⋅[gcd(i,dn​)]

显然它的实际含义为:1∼n1\sim n1∼n 中所有与 nnn 互质的数的和。

显然和为 φ(n)⋅n2\cfrac{\varphi(n)\cdot n} 22φ(n)⋅n​

即:
f(x)=φ(n)⋅n2f(x)=\cfrac{\varphi(n)\cdot n} 2f(x)=2φ(n)⋅n​

即:

ans=n×∑d∣n∑i=1⌊nd⌋i⋅[gcd⁡(i,nd)]=n×∑d∣nφ(d)⋅d2=n×∑d∣nf(d)\begin{aligned}\displaystyle ans&=n\times \sum_{d\mid n}\sum_{i=1}^{ \lfloor\frac n d \rfloor} i\cdot [\gcd(i,\frac n d)]&\\&=n\times \sum_{d\mid n}\cfrac{\varphi(d)\cdot d} 2&\\&=n\times \sum_{d\mid n}f(d)\end{aligned} ans​=n×d∣n∑​i=1∑⌊dn​⌋​i⋅[gcd(i,dn​)]=n×d∣n∑​2φ(d)⋅d​=n×d∣n∑​f(d)​​

显然可以先预处理出所有的 f(n)f(n)f(n) ,然后利用 Dirichlet\text{Dirichlet}Dirichlet 前缀和计算 ∑d∣nf(d)\displaystyle \sum_{d\mid n}f(d)d∣n∑​f(d) 即可。

时间复杂度 O(nlog⁡n+T)O(n\log n +T)O(nlogn+T)

方法二:

当然本题还有 O(n)O(n)O(n) 的做法。

我们重新推一遍:

∑i=1ni⋅ngcd⁡(i,n)\sum_{i=1}^n \frac{i\cdot n}{\gcd(i,n)} i=1∑n​gcd(i,n)i⋅n​

将原式复制一份并且颠倒顺序,然后将 n 一项单独提出,可得

12⋅(∑i=1n−1i⋅ngcd⁡(i,n)+∑i=n−11i⋅ngcd⁡(i,n))+n\frac{1}{2}\cdot \left(\sum_{i=1}^{n-1}\frac{i\cdot n}{\gcd(i,n)}+\sum_{i=n-1}^{1}\frac{i\cdot n}{\gcd(i,n)}\right)+n 21​⋅(i=1∑n−1​gcd(i,n)i⋅n​+i=n−1∑1​gcd(i,n)i⋅n​)+n

根据 gcd⁡(i,n)=gcd⁡(n−i,n)\gcd(i,n)=\gcd(n-i,n)gcd(i,n)=gcd(n−i,n),可将原式化为

12⋅(∑i=1n−1i⋅ngcd⁡(i,n)+∑i=n−11i⋅ngcd⁡(n−i,n))+n\frac{1}{2}\cdot \left(\sum_{i=1}^{n-1}\frac{i\cdot n}{\gcd(i,n)}+\sum_{i=n-1}^{1}\frac{i\cdot n}{\gcd(n-i,n)}\right)+n 21​⋅(i=1∑n−1​gcd(i,n)i⋅n​+i=n−1∑1​gcd(n−i,n)i⋅n​)+n

两个求和式中分母相同的项可以合并。

12⋅∑i=1n−1n2gcd⁡(i,n)+n\frac{1}{2}\cdot \sum_{i=1}^{n-1}\frac{n^2}{\gcd(i,n)}+n 21​⋅i=1∑n−1​gcd(i,n)n2​+n

12⋅∑i=1nn2gcd⁡(i,n)+n2\frac{1}{2}\cdot \sum_{i=1}^{n}\frac{n^2}{\gcd(i,n)}+\frac{n}{2} 21​⋅i=1∑n​gcd(i,n)n2​+2n​

可以将相同的 gcd⁡(i,n)\gcd(i,n)gcd(i,n) 合并在一起计算,故只需要统计 gcd⁡(i,n)=d\gcd(i,n)=dgcd(i,n)=d 的个数。当 gcd⁡(i,n)=d\gcd(i,n)=dgcd(i,n)=d 时,gcd⁡(id,nd)=1\displaystyle\gcd(\frac{i}{d},\frac{n}{d})=1gcd(di​,dn​)=1,所以 gcd⁡(i,n)=d\gcd(i,n)=dgcd(i,n)=d 的个数有 φ(nd)\displaystyle\varphi(\frac{n}{d})φ(dn​) 个。

故答案为

12⋅∑d∣nn2⋅φ(nd)d+n2\frac{1}{2}\cdot\sum_{d\mid n}\frac{n^2\cdot\varphi(\frac{n}{d})}{d}+\frac{n}{2} 21​⋅d∣n∑​dn2⋅φ(dn​)​+2n​

变换求和顺序,设 d′=nd\displaystyle d'=\frac{n}{d}d′=dn​,合并公因式,式子化为

12n⋅(∑d′∣nd′⋅φ(d′)+1)\frac{1}{2}n\cdot\left(\sum_{d'\mid n}d'\cdot\varphi(d')+1\right) 21​n⋅⎝⎛​d′∣n∑​d′⋅φ(d′)+1⎠⎞​

我们可以设 g(n)=∑d∣nd×φ(d)\displaystyle \text g(n)=\sum_{d\mid n}d\times \varphi(d)g(n)=d∣n∑​d×φ(d)

显然函数 ggg 是一个积性函数,我们可以利用线性筛 O(n)O(n)O(n) 筛出 ggg :

1. 考虑 g⁡(pjk)\operatorname g(p_j^k)g(pjk​)

显然它的约数只有 pj0,pj1,⋯,pjkp_j^0,p_j^1,\cdots,p_j^kpj0​,pj1​,⋯,pjk​,因此
g⁡(pjk)=∑c=0kpjc×φ(pjc)\operatorname g(p_j^k)=\sum_{c=0}^{k}p_j^c\times \varphi(p_j^c) g(pjk​)=c=0∑k​pjc​×φ(pjc​)

又有 φ(pjc)=pjc−1⋅(pj−1)\varphi(p_j^c)=p_j^{c-1}\cdot(p_j-1)φ(pjc​)=pjc−1​⋅(pj​−1),则原式可化为

∑c=0kpj2c−1×(pj−1)\sum_{c=0}^{k}p_j^{2c-1}\times (p_j-1) c=0∑k​pj2c−1​×(pj​−1)

于是有

g⁡(pjk+1)=g⁡(pjk)+pj2k+1×(pj−1)\operatorname g(p_j^{k+1})=\operatorname g(p_j^k)+p_j^{2k+1}\times (p_j-1) g(pjk+1​)=g(pjk​)+pj2k+1​×(pj​−1)

2. 考虑 g⁡(i×pj)\operatorname g(i\times p_j)g(i×pj​), pj∣ip_j\mid ipj​∣i

令 i=a×pjc(gcd⁡(a,pj)=1)i=a\times p_j^c(\operatorname{gcd}(a,p_j)=1)i=a×pjc​(gcd(a,pj​)=1),可得
g⁡(i×pj)=g⁡(a)×g⁡(pjc+1)\operatorname g(i\times p_j)=\operatorname g(a)\times \operatorname g(p_j^{c+1}) g(i×pj​)=g(a)×g(pjc+1​)

g⁡(i)=g⁡(a)×g⁡(pjc)\operatorname g(i)=\operatorname g(a)\times \operatorname g(p_j^c) g(i)=g(a)×g(pjc​)

显然有:

g⁡(i×pj)−g⁡(i)=g(a)×g(pjc+1)−g(a)×g(pjc)=g(a)×(g(pjc)+pj2c+1×(pj−1))−g(a)×g(pjc)=g⁡(a)×pj2c+1×(pj−1)\begin{aligned}\operatorname g(i\times p_j)-\operatorname g(i)&=\text g(a)\times \text g(p_j^{c+1})-\text g(a)\times \text g(p_j^{c})&\\&=\text g(a)\times (\text g(p_j^c)+p_j^{2c+1}\times (p_j-1))-\text g(a)\times \text g(p_j^{c})&\\&=\operatorname g(a)\times p_j^{2c+1}\times (p_j-1)\end{aligned} g(i×pj​)−g(i)​=g(a)×g(pjc+1​)−g(a)×g(pjc​)=g(a)×(g(pjc​)+pj2c+1​×(pj​−1))−g(a)×g(pjc​)=g(a)×pj2c+1​×(pj​−1)​​

同理有

g⁡(i)−g⁡(ipj)=g⁡(a)×pj2c−1×(pj−1)\operatorname g(i)-\operatorname g(\frac{i}{p_j})=\operatorname g(a)\times p_j^{2c-1}\times (p_j-1) g(i)−g(pj​i​)=g(a)×pj2c−1​×(pj​−1)

因此

g⁡(i×pj)=g⁡(i)+(g⁡(i)−g⁡(ipj))×pj2\operatorname g(i\times p_j)=\operatorname g(i)+\left (\operatorname g(i)-\operatorname g(\frac{i}{p_j})\right )\times p_j^2 g(i×pj​)=g(i)+(g(i)−g(pj​i​))×pj2​
3. 考虑 g⁡(i×pj)\operatorname g(i\times p_j)g(i×pj​),当 pj∤ip_j\nmid ipj​∤i

积性函数,显然 g⁡(i×pj)=g(i)×g(pj)\operatorname g(i\times p_j)=\text{g}(i)\times \text{g}(p_j)g(i×pj​)=g(i)×g(pj​)

时间复杂度 O(n+T)O(n+T)O(n+T)

Code1

O(nlog⁡n+T)O(n\log n+T)O(nlogn+T)

typedef long long ll;
typedef pair<int , int> PII;
const int N = 5000007, M = 500007, T = 1000, Mod = 998244353, INF = 0x3f3f3f3f;int phi[N];
bool vis[N];
ll f[N], g[N];
int primes[N], cnt;void get_phi(int n)
{phi[1] = 1;f[1] = 1;for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;phi[i] = i - 1;}f[i] = 1ll * phi[i] * i / 2;for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) {phi[i * primes[j]] = phi[i] * primes[j];break;}else phi[i * primes[j]] = phi[i] * (primes[j] - 1);}}for(int j = 1; j <= cnt; ++ j) {for(int i = 1; i * primes[j] <= n; ++ i) {f[i * primes[j]] += f[i];}}
}int n, t;void slove()
{scanf("%d", &n);printf("%lld\n", f[n] * n);
}int main()
{scanf("%d", &t);get_phi(N - 1);while(t -- ) {slove();}
}

Code2

O(n+T)O(n+T)O(n+T)

using ll = long long;
const int N = 1e6 + 7;int n, m, s, t, k, ans, a[N];
int primes[N], cnt;
ll g[N];
bool vis[N];void pre_work(int n)
{vis[1] = 1;g[1] = 1;for (int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;g[i] = 1ll * i * (i - 1) + 1;}for (int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = 1;if(i % primes[j] == 0) {g[i * primes[j]] = g[i] + (g[i] - g[i / primes[j]]) * primes[j] * primes[j];break;}g[i * primes[j]] = g[i] * g[primes[j]];}}
}void solve()
{scanf("%d", &n);printf("%lld\n", (g[n] + 1) * n / 2ll);
}int main()
{pre_work(N - 7);scanf("%d", &t);while(t -- ) {solve();}return 0;
}

Problem C. 约数个数和 (P3327 [SDOI2015])

Solution


Code

const int N = 50007;
typedef long long ll;
int n, m, t;
int primes[N];
ll res;
bool vis[N];
int mu[N], sum[N], cnt, H[N];
int g(int k, int x) {return k / (k / x);}
void init(int n)
{mu[1] = 1;for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;mu[i] = -1;}for(int j = 1; j <= cnt && primes[j] * i <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) break;mu[i * primes[j]] = -mu[i];}}for(int i = 1; i <= n; ++ i) sum[i] = sum[i - 1] + mu[i];for(int i = 1; i <= n; ++ i) {for(int l = 1, r; l <= i; l = r + 1) {r = min(i, g(i, l));H[i] += (r - l + 1) * (i / l);}}
}int main()
{cin >> t;init(N - 1);while(t -- ) {res = 0;scanf("%d%d", &n, &m);int k = min(n, m);for(int l = 1, r; l <= k; l = r + 1) {r = min(k, min(g(n, l), g(m, l)));res += ((ll)sum[r] - sum[l - 1]) * H[n / l] * H[m / l];}printf("%lld\n", res);}return 0;
}

Problem D.Crash 的数字表格 (Luogu P1829)

计算(对 201010092010100920101009 取模)

∑i=1n∑j=1mlcm⁡(i,j)(n,m⩽107)\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j)\qquad (n,m\leqslant 10^7) i=1∑n​j=1∑m​lcm(i,j)(n,m⩽107)

Solution

Code

#define int long long
const int N = 10000007, mod = 20101009;int n, m;
int primes[N], cnt, f[N], g[N];
bool vis[N];void init(int n)
{g[1] = f[1] = 1;for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;f[i] = (1 - i % mod + mod) % mod;}for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) {f[i * primes[j]] = f[i];break;}f[i * primes[j]] = (f[i] * f[primes[j]]) % mod;}}for(int i = 1; i <= n; ++ i) {g[i] = (f[i] * i % mod + g[i - 1]) % mod;}
}int s(int x)
{return (x * (x + 1) / 2) % mod;
}int ans;signed main()
{init(N - 7);scanf("%lld%lld", &n, &m);if(n > m)  swap(n, m);ans = 0;for(int l = 1, r; l <= n; l = r + 1) {r = min(n / (n / l), m / (m / l));ans = (ans + (s(n / l) * s(m / l) % mod) * (g[r] - g[l - 1] + mod) + mod % mod) % mod;}printf("%lld\n", ans);return 0;
}

Problem E. 简单的数学题 (luogu P3768)

前置知识:0x52 杜教筛

输入一个整数 nnn 和一个整数 ppp,你需要求出:

(∑i=1n∑j=1nijgcd⁡(i,j))modp\left(\sum_{i=1}^n\sum_{j=1}^n ij \gcd(i,j)\right) \bmod p(i=1∑n​j=1∑n​ijgcd(i,j))modp
其中 gcd⁡(a,b)\gcd(a,b)gcd(a,b) 表示 aaa 与 bbb 的最大公约数。

n≤1010n \leq 10^{10}n≤1010 ,5×108≤p≤1.1×1095 \times 10^8 \leq p \leq 1.1 \times 10^95×108≤p≤1.1×109 且 ppp 为质数。

Solution


Hint

注意一点:这种需要输入模数mod的题,一定要等输入模数之后再初始化 init …不然会RE…膜0可不就RE了嘛…

Time

% %

O(n23)O(n^{\frac{2}{3}})O(n32​)

Code

#define int long long
typedef long long ll;
const int N = 4641589;// ⌈(10^10)^(2/3)⌉int primes[N + 7], cnt;
ll phi[N + 7];
bool vis[N + 7];
unordered_map<ll, ll> sum_f;
int mod, n;
int inv4, inv6;int qpow(int a, int b)
{int res = 1;while(b) {if(b & 1) res = 1ll * res * a % mod;a = 1ll * a * a % mod;b >>= 1;}return res % mod;
}void init(int n)
{phi[1] = 1;for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;phi[i] = i - 1;}for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) {phi[i * primes[j]] = 1ll * phi[i] * primes[j] % mod;break;}phi[i * primes[j]] = 1ll * phi[i] * phi[primes[j]] % mod;}}for(int i = 1; i <= n; ++ i) {phi[i] = (1ll * phi[i - 1] + (1ll * phi[i] * i % mod * i % mod)) % mod; }
}inline int g_sum(int n) //i^2
{n %= mod;return 1ll * n * inv6 % mod * (n + 1) % mod * (2 * n + 1) % mod;
}inline int h_sum(int n) //i^3
{n %= mod;return 1ll * n * inv4 % mod * n % mod * (n + 1) % mod * (n + 1) % mod;
}inline int get_s_sum(int x)
{if(x <= N - 7) return phi[x];if(sum_f.find(x) != sum_f.end()) return sum_f[x];ll ans = h_sum(x);for(ll l = 2, r; l <= x; l = r + 1) {r = x / (x / l);ans = (ans - 1ll * (g_sum(r) - g_sum(l - 1) + mod) % mod * get_s_sum(x / l) % mod) % mod ;}return sum_f[x] = ans / g_sum(1);
}void solve(int n)
{ll ans = 0;for(int l = 1, r; l <= n; l = r + 1) {r = n / (n / l);ans = (ans + (1ll * h_sum(n / l) * (get_s_sum(r) - get_s_sum(l - 1) + mod) % mod)) % mod;}printf("%lld\n", ans);return ;
}signed main()
{scanf("%lld%lld", &mod, &n);  init(N - 7);inv4 = qpow(4, mod - 2);inv6 = qpow(6, mod - 2);solve(n);//cout << "ok" << endl;return 0;
}

趣味题目

Problem F. Gcd Product(2020 ICPC 济南 F )

Solution


Code

#define int long long
const int N = 5e5 + 7, mod = 998244353;int n, m;
int a[N], b[N], c[N];
int primes[N], cnt, mu[N], phi[N];
bool vis[N];
int f[N], g[N], h[N];void init(int n)
{mu[1] = phi[1] = 1;for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;phi[i] = i - 1;mu[i] = -1;}for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) {phi[i * primes[j]] = phi[i] * primes[j];break;}phi[i * primes[j]] = phi[i] * (primes[j] - 1);mu[i * primes[j]] -= mu[i];}}
}int ans = 0;signed main()
{init(N - 7);scanf("%lld", &n);for(int i = 1; i <= n; ++ i) {scanf("%lld", &a[i]);}for(int i = 1; i <= n; ++ i) {scanf("%lld", &b[i]);}for(int i = 1; i <= n; ++ i) {for(int j = i; j <= n; j += i) {if(mu[i] == 0) continue;f[j] = ((f[j] + mu[i] * a[j / i]) % mod + mod) % mod;g[j] = ((g[j] + mu[i] * b[j / i]) % mod + mod) % mod;}}for(int i = 1; i <= n; ++ i) {for(int j = i; j <= n; j += i) {if(phi[i] * phi[j / i] == phi[j]) {//if(__gcd(i, j / i) == 1) {h[j] = (h[j] + f[i] * g[j / i] % mod) % mod;}}}for(int i = 1; i <= n; ++ i) {for(int j = i; j <= n; j += i) {c[j] = (c[j] + h[i] * j / i % mod) % mod;}}for(int i = 1; i <= n; ++ i) {ans = (ans ^ c[i]);}printf("%lld\n", ans);return 0;
}

0x42.5 莫比乌斯反演扩展

莫比乌斯反演的非卷积形式

对于数论函数 f,gf,gf,g 和完全积性函数 ttt 且 t(1)=1t(1)=1t(1)=1:

f(n)=∑i=1nt(i)g(⌊ni⌋)⟺g(n)=∑i=1nμ(i)t(i)f(⌊ni⌋)f(n)=\sum_{i=1}^nt(i)\text g\left(\left\lfloor\frac{n}{i}\right\rfloor\right)\\ \iff \\\text g(n)=\sum_{i=1}^n\mu(i)t(i)f\left(\left\lfloor\frac{n}{i}\right\rfloor\right) f(n)=i=1∑n​t(i)g(⌊in​⌋)⟺g(n)=i=1∑n​μ(i)t(i)f(⌊in​⌋)

证明

g(n)=∑i=1nμ(i)t(i)f(⌊ni⌋)=∑i=1nμ(i)t(i)∑j=1⌊ni⌋t(j)g(⌊⌊ni⌋j⌋)=∑i=1nμ(i)t(i)∑j=1⌊ni⌋t(j)g(⌊nij⌋)=∑T=1n∑i=1nμ(i)t(i)∑j=1⌊ni⌋[ij=T]t(j)g(⌊nT⌋)【先枚举 ij 乘积】=∑T=1n∑i∣Tμ(i)t(i)t(Ti)g(⌊nT⌋)【∑j=1⌊ni⌋[ij=T]对答案的贡献为 1,于是省略】=∑T=1ng(⌊nT⌋)∑i∣Tμ(i)t(i)t(Ti)=∑T=1ng(⌊nT⌋)∑i∣Tμ(i)t(T)【t 是完全积性函数】=∑T=1ng(⌊nT⌋)t(T)∑i∣Tμ(i)=∑T=1ng(⌊nT⌋)t(T)ε(T)【μ∗1=ε】=g(n)t(1)【当且仅当 T=1,ε(T)=1时】=g(n)□\begin{aligned} \text g(n)&=\sum_{i=1}^n\mu(i)t(i)f\left(\left\lfloor\frac{n}{i}\right\rfloor\right)\\ &=\sum_{i=1}^n\mu(i)t(i) \sum_{j=1}^{\left\lfloor\frac{n}{i}\right\rfloor}t(j) \text g\left(\left\lfloor\frac{\left\lfloor\frac{n}{i}\right\rfloor}{j}\right\rfloor\right)\\ &=\sum_{i=1}^n\mu(i)t(i) \sum_{j=1}^{\left\lfloor\frac{n}{i}\right\rfloor}t(j) \text g\left(\left\lfloor\frac{n}{ij}\right\rfloor\right)\\ &=\sum_{T=1}^n \sum_{i=1}^n\mu(i)t(i) \sum_{j=1}^{\left\lfloor\frac{n}{i}\right\rfloor}[ij=T] t(j)\text g\left(\left\lfloor\frac{n}{T}\right\rfloor\right) &\text{【先枚举 ij 乘积】}\\ &=\sum_{T=1}^n \sum_{i \mid T}\mu(i)t(i) t\left(\frac{T}{i}\right)\text g\left(\left\lfloor\frac{n}{T}\right\rfloor\right) &\text{【}\sum_{j=1}^{\left\lfloor\frac{n}{i}\right\rfloor}[ij=T] \text{对答案的贡献为 1,于是省略】}\\ &=\sum_{T=1}^n\text g\left(\left\lfloor\frac{n}{T}\right\rfloor\right) \sum_{i \mid T}\mu(i)t(i)t\left(\frac{T}{i}\right)\\ &=\sum_{T=1}^n\text g\left(\left\lfloor\frac{n}{T}\right\rfloor\right) \sum_{i \mid T}\mu(i)t(T) &\text{【t 是完全积性函数】}\\ &=\sum_{T=1}^n\text g\left(\left\lfloor\frac{n}{T}\right\rfloor\right)t(T) \sum_{i \mid T}\mu(i)\\ &=\sum_{T=1}^n\text g\left(\left\lfloor\frac{n}{T}\right\rfloor\right)t(T) \varepsilon(T) &\text{【}\mu\ast 1= \varepsilon\text{】}\\ &=\text g(n)t(1) &\text{【当且仅当 T=1,}\varepsilon(T)=1\text{时】}\\ &=\text g(n) & \square \end{aligned} g(n)​=i=1∑n​μ(i)t(i)f(⌊in​⌋)=i=1∑n​μ(i)t(i)j=1∑⌊in​⌋​t(j)g(⌊j⌊in​⌋​⌋)=i=1∑n​μ(i)t(i)j=1∑⌊in​⌋​t(j)g(⌊ijn​⌋)=T=1∑n​i=1∑n​μ(i)t(i)j=1∑⌊in​⌋​[ij=T]t(j)g(⌊Tn​⌋)=T=1∑n​i∣T∑​μ(i)t(i)t(iT​)g(⌊Tn​⌋)=T=1∑n​g(⌊Tn​⌋)i∣T∑​μ(i)t(i)t(iT​)=T=1∑n​g(⌊Tn​⌋)i∣T∑​μ(i)t(T)=T=1∑n​g(⌊Tn​⌋)t(T)i∣T∑​μ(i)=T=1∑n​g(⌊Tn​⌋)t(T)ε(T)=g(n)t(1)=g(n)​【先枚举 ij 乘积】【j=1∑⌊in​⌋​[ij=T]对答案的贡献为 1,于是省略】【t 是完全积性函数】【μ∗1=ε】【当且仅当 T=1,ε(T)=1时】□​

0x43 欧拉反演

本身是没有欧拉反演这个东西的,在刘汝佳的蓝书上讲过一道利用欧拉函数的性质简便求解答案的题目,由于和莫比乌斯反演雷同,都是由一个基本性质推出一个反演公式,慢慢大家也将这种方法叫做欧拉反演。

我们知道欧拉函数的基本性质:

φ∗1=id⇒n=∑d∣nφ(d)\begin{aligned}\varphi*1&=id\Rightarrow n=\sum_{d|n}\varphi(d)\end{aligned}φ∗1​=id⇒n=d∣n∑​φ(d)​

(性质的证明详见 0x33.1 常见积性函数的卷积的 性质0x33.5

我们就可以利用这个性质,将 nnn 换成我们想要求的东西,来直接求解答案(反演)。

例如我们可以令 n=gcd⁡(i,j)n=\gcd(i,j)n=gcd(i,j),显然有( d∣gcd⁡(i,j)→gcd⁡(i,j)∣i,j→d∣i,jd|\gcd(i,j)\to\gcd(i,j)|i,j\to d|i,jd∣gcd(i,j)→gcd(i,j)∣i,j→d∣i,j):

gcd⁡(i,j)=∑d∣gcd(i,j)φ(d)=∑d∣i∑d∣jφ(d)\begin{aligned}\gcd(i,j)&=\sum_{d|gcd(i,j)}\varphi(d)\\&=\sum_{d|i}\sum_{d|j}\varphi(d)\end{aligned}gcd(i,j)​=d∣gcd(i,j)∑​φ(d)=d∣i∑​d∣j∑​φ(d)​

我们可以尝试使用一下这个式子:

∑i=1ngcd⁡(i,n)=∑i=1n∑d∣i∑d∣nφ(d)=∑d∣n∑i=1n∑d∣iφ(d)=∑d∣n⌊nd⌋φ(d)\begin{aligned}\sum_{i=1}^n\gcd(i,n)&=\sum_{i=1}^n\sum_{d|i}\sum_{d|n}\varphi(d)\\&=\sum_{d|n}\sum_{i=1}^n\sum_{d|i}\varphi(d)\\&=\sum_{d|n}\lfloor\frac{n}{d}\rfloor\varphi(d)\end{aligned}i=1∑n​gcd(i,n)​=i=1∑n​d∣i∑​d∣n∑​φ(d)=d∣n∑​i=1∑n​d∣i∑​φ(d)=d∣n∑​⌊dn​⌋φ(d)​

一些结论:

结论43.1:∑i=1n∑j=1ngcd⁡(i,j)=∑d=1nd(2∑i=1⌊nd⌋φ(i)−1)\displaystyle \sum_{i=1}^{n} \sum_{j=1}^{n} \gcd(i,j)=\sum_{d=1}^{n}d\left(2\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}{\varphi(i)}-1\right)i=1∑n​j=1∑n​gcd(i,j)=d=1∑n​d⎝⎛​2i=1∑⌊dn​⌋​φ(i)−1⎠⎞​
结论43.2:∑i=1n∑j=1mgcd⁡(i,j)=∑d=1nφ(d)⌊nd⌋⌊md⌋\displaystyle \sum_{i=1}^{n} \sum_{j=1}^{m} \gcd(i,j)=\sum_{d=1}^{n} \varphi(d) \lfloor\frac{n}{d}\rfloor \lfloor\frac{m}{d}\rfloori=1∑n​j=1∑m​gcd(i,j)=d=1∑n​φ(d)⌊dn​⌋⌊dm​⌋(例题)
结论43.3:∏i=1n∏j=1n(lcm⁡(i,j)gcd⁡(i,j))=(n!)2n(∏d=1nd(2Sφ(⌊na⌋)−1))2\displaystyle \prod_{i=1}^{n} \prod_{j=1}^{n} \left(\frac{\operatorname{lcm}(i,j)}{\gcd(i,j)}\right)=\frac{(n!)^{2n}}{\left(\prod_{d=1}^{n} d^{\left(2 S_{\varphi}(\lfloor\frac{n}{a}\rfloor)-1\right)}\right)^{2}}i=1∏n​j=1∏n​(gcd(i,j)lcm(i,j)​)=(∏d=1n​d(2Sφ​(⌊an​⌋)−1))2(n!)2n​(例题)


竞赛例题选讲

Problem A. 能量采集(P1447 [NOI2010] )


Solution

方法一: 莫比乌斯反演 + 欧拉反演

先简单解释一下本题解题第一步用到的显然的结论。

数轴上任意一点 (x1,y1)(x_1,y_1)(x1​,y1​) 到原点之间线段上的经过的点 (x2,y2)(x_2,y_2)(x2​,y2​) ,gcd⁡(x2,y2)\gcd(x_2,y_2)gcd(x2​,y2​) 一定是 gcd⁡(x1,y1)\gcd(x_1,y_1)gcd(x1​,y1​) 的因子。例如仪仗队那道题,从原点出发能看到的点一定都是 gcd⁡(x,y)=1\gcd(x, y)=1gcd(x,y)=1 的点。从原点到 (x1,y1)(x_1,y_1)(x1​,y1​) 所以经过的点的个数就是 gcd⁡(x1,y1)−1\gcd(x_1,y_1)-1gcd(x1​,y1​)−1(去掉自身)( (2,4)(2,4)(2,4) 会有因子 (1,2)(1,2)(1,2) )

证明来源:

Time

O(n+n)O(n+\sqrt n)O(n+n​)

Code

const int N = 500007;
int primes[N], cnt, phi[N];
int n, m;
bool vis[N];
int sum[N];void init(int n)
{phi[1] = 1; for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) {primes[ ++ cnt] = i;phi[i] = i - 1;}for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) {phi[i * primes[j]] = phi[i] * primes[j];break;} phi[i * primes[j]] = phi[i] * phi[primes[j]];}}for(int i = 1; i <= n; ++ i) {sum[i] = sum[i - 1] + phi[i];   }
}void solve()
{int res = 0;for(int l = 1, r; l <= n; l = r + 1) {r = min(n / (n / l), m / (m / l));res +=  (n / l) * (m / l) * (sum[r] - sum[l - 1]);//(sum[r] - sum[l - 1])已经是区间长度了}res = 2 * res - n * m;printf("%lld\n", res);
}signed main()
{init(N - 7);scanf("%lld%lld", &n, &m);if(n > m) swap(n, m);solve();return 0;
}

方法二: 容斥原理

有趣的是,我们可以利用容斥原理解决这个问题。

时间复杂度 O(nlog⁡n)O(n\log n)O(nlogn)


Code

#define int long long
using namespace std;const int N = 500007;int n, m;
int f[N];signed main()
{scanf("%lld%lld", &n, &m);if(n > m) swap(n, m);int ans = 0;for(int i = n; i; -- i) {f[i] = (n / i) * (m / i);for(int j = i << 1; j <= n; j += i) f[i] -= f[j];ans += (2 * i - 1) * f[i];}printf("%lld\n", ans);return 0;
}

0x44 二项式反演1

我们知道容斥原理的一般形式为

∣A1‾∩...∩An‾∣=∣A∣−∑i=1n∣Ai∣+∑1≤i1<i2≤n∣Ai1∩Ai2∣−...+(−1)n⋅∣A1∩...∩An∣|\overline{A_1} \cap ... \cap \overline{A_n}| = |A| - \sum\limits_{i=1}^n |A_i| + \sum\limits_{1 \leq i_1 < i_2 \leq n} |A_{i_1} \cap A_{i_2}| -... + (-1)^n \cdot |A_1 \cap ... \cap A_n| ∣A1​​∩...∩An​​∣=∣A∣−i=1∑n​∣Ai​∣+1≤i1​<i2​≤n∑​∣Ai1​​∩Ai2​​∣−...+(−1)n⋅∣A1​∩...∩An​∣

那么根据德摩根定律显然有
∣A1∪...∪An‾∣+∣A1‾∩...∩An‾∣=∣A∣|\overline{A_1 \cup ...\cup A_n}|+|\overline{A_1}\cap ...\cap \overline{A_n}|=|A| ∣A1​∪...∪An​​∣+∣A1​​∩...∩An​​∣=∣A∣

∣A1∪A2∪...∪An∣=∑1≤i≤n∣Ai∣−∑1≤i<j≤n∣Ai∩Aj∣+...+(−1)n−1×∣A1∩A2∩...∩An∣|A_1\cup A_2\cup...\cup A_n|=\sum\limits_{1\le i\le n}|A_i|-\sum\limits_{1\le i<j\le n}|A_i\cap A_j|+...+(-1)^{n-1}\times |A_1\cap A_2\cap ...\cap A_n| ∣A1​∪A2​∪...∪An​∣=1≤i≤n∑​∣Ai​∣−1≤i<j≤n∑​∣Ai​∩Aj​∣+...+(−1)n−1×∣A1​∩A2​∩...∩An​∣

那么我们设 AicA_i^cAic​ 为 AiA_iAi​ 的补集,变形可得
∣A1c∩A2c∩...∩Anc∣=∣S∣−∑1≤i≤n∣Ai∣+∑1≤i<j≤n∣Ai∩Aj∣−...+(−1)n×∣A1∩A2∩...∩An∣|A_1^c\cap A_2^c\cap ...\cap A_n^c|=|S|-\sum\limits_{1\le i\le n}|A_i|+\sum\limits_{1\le i<j\le n}|A_i\cap A_j|-...+(-1)^n\times |A_1\cap A_2\cap ...\cap A_n| ∣A1c​∩A2c​∩...∩Anc​∣=∣S∣−1≤i≤n∑​∣Ai​∣+1≤i<j≤n∑​∣Ai​∩Aj​∣−...+(−1)n×∣A1​∩A2​∩...∩An​∣
显然补集的补集就是原集,则有
∣A1∩A2∩...∩An∣=∣S∣−∑1≤i≤n∣Aic∣+∑1≤i<j≤n∣Aic∩Ajc∣−...+(−1)n×∣A1c∩A2c∩...∩Anc∣|A_1\cap A_2\cap ...\cap A_n|=|S|-\sum\limits_{1\le i\le n}|A_i^c|+\sum\limits_{1\le i<j\le n}|A_i^c\cap A_j^c|-...+(-1)^n\times |A_1^c\cap A_2^c\cap ...\cap A_n^c| ∣A1​∩A2​∩...∩An​∣=∣S∣−1≤i≤n∑​∣Aic​∣+1≤i<j≤n∑​∣Aic​∩Ajc​∣−...+(−1)n×∣A1c​∩A2c​∩...∩Anc​∣
设 f(n)f(n)f(n) 表示 nnn 个补集的交集大小,g(n)\text g(n)g(n) 表示 nnn 个原集的大小


∣A1c∩A2c∩...∩Anc∣=∣S∣−∑1≤i≤n∣Ai∣+∑1≤i<j≤n∣Ai∩Aj∣−...+(−1)n×∣A1∩A2∩...∩An∣|A_1^c\cap A_2^c\cap ...\cap A_n^c|=|S|-\sum\limits_{1\le i\le n}|A_i|+\sum\limits_{1\le i<j\le n}|A_i\cap A_j|-...+(-1)^n\times |A_1\cap A_2\cap ...\cap A_n| ∣A1c​∩A2c​∩...∩Anc​∣=∣S∣−1≤i≤n∑​∣Ai​∣+1≤i<j≤n∑​∣Ai​∩Aj​∣−...+(−1)n×∣A1​∩A2​∩...∩An​∣
即可表示为
f(n)=∑i=0n(−1)i(ni)g(i)f(n)=\sum\limits_{i=0}^n(-1)^i{n\choose i}\text g(i) f(n)=i=0∑n​(−1)i(in​)g(i)

而第二个等式

∣A1∩A2∩...∩An∣=∣S∣−∑1≤i≤n∣Aic∣+∑1≤i<j≤n∣Aic∩Ajc∣−...+(−1)n×∣A1c∩A2c∩...∩Anc∣|A_1\cap A_2\cap ...\cap A_n|=|S|-\sum\limits_{1\le i\le n}|A_i^c|+\sum\limits_{1\le i<j\le n}|A_i^c\cap A_j^c|-...+(-1)^n\times |A_1^c\cap A_2^c\cap ...\cap A_n^c| ∣A1​∩A2​∩...∩An​∣=∣S∣−1≤i≤n∑​∣Aic​∣+1≤i<j≤n∑​∣Aic​∩Ajc​∣−...+(−1)n×∣A1c​∩A2c​∩...∩Anc​∣

即可表示为

g(n)=∑i=0n(−1)i(ni)f(i)\text g(n)=\sum\limits_{i=0}^n(-1)^i{n\choose i}f(i) g(n)=i=0∑n​(−1)i(in​)f(i)

即:
f(n)=∑i=0n(−1)i(ni)g(i)⇔g(n)=∑i=0n(−1)i(ni)f(i)f(n)=\sum\limits_{i=0}^n(-1)^i{n\choose i}g(i)\Leftrightarrow \text g(n)=\sum\limits_{i=0}^n(-1)^i{n\choose i}f(i) f(n)=i=0∑n​(−1)i(in​)g(i)⇔g(n)=i=0∑n​(−1)i(in​)f(i)
我们令 h(n)=(−1)ng(n)h(n)=(-1)^n\text g(n)h(n)=(−1)ng(n) 带入上述公式即可得到二项式反演的第一种形式

二项式反演的第一种形式
f(n)=∑i=0n(ni)h(i)⇔h(n)(−1)n=∑i=0n(−1)i(ni)f(i)f(n)=\sum\limits_{i=0}^n{n\choose i}h(i)\Leftrightarrow \frac{h(n)}{(-1)^n}=\sum\limits_{i=0}^n(-1)^i{n\choose i}f(i) f(n)=i=0∑n​(in​)h(i)⇔(−1)nh(n)​=i=0∑n​(−1)i(in​)f(i)

更一般的形式为:
f(n)=∑i=mn(ni)g(i)⇔g(n)=∑i=mn(−1)n−i(ni)f(i)f(n)=\sum\limits_{i=m}^n{n\choose i}\text g(i)\Leftrightarrow \text g(n)=\sum\limits_{i=m}^n(-1)^{n-i}{n\choose i}f(i) f(n)=i=m∑n​(in​)g(i)⇔g(n)=i=m∑n​(−1)n−i(in​)f(i)
二项式反演的第二种形式
f(n)=∑i=nm(in)g(i)⇔g(n)=∑i=nm(−1)i−n(in)f(i)f(n)=\sum\limits_{i=n}^m{i\choose n}\text g(i)\Leftrightarrow \text g(n)=\sum\limits_{i=n}^m(-1)^{i-n}{i\choose n}f(i) f(n)=i=n∑m​(ni​)g(i)⇔g(n)=i=n∑m​(−1)i−n(ni​)f(i)

二项式反演的第二种形式中,我们设 f(n)f(n)f(n) 表示 “钦定选择 nnn 个” 的方案数, g(n)\text g(n)g(n) 表示 “恰好选 nnn 个” 的方案数,f(n)f(n)f(n) 表示先钦定 nnn 个,再统计在已经钦定的情况下的方案数,那么对于任意的 i≥ni≥ni≥n ,在 f(n)f(n)f(n) 中被计算了 (in)\displaystyle {i\choose n}(ni​) 次,故 f(n)=∑i=nm(in)g(i)\displaystyle f(n)=\sum\limits_{i=n}^m{i\choose n}\text g(i)f(n)=i=n∑m​(ni​)g(i) ,其中 mmm 是数目上界。而对于恰好选择了 iii 个,从 iii 个中钦定 nnn 个的方案数显然为 (in)i\choose n(ni​),即 g(i)\text g(i)g(i) 也在 f(i)f(i)f(i)中被计算了 (in)\displaystyle {i\choose n}(ni​) 次,然后根据容斥原理,可得 g(n)=∑i=nm(−1)i−n(in)f(i)\displaystyle \text g(n)=\sum\limits_{i=n}^m(-1)^{i-n}{i\choose n}f(i)g(n)=i=n∑m​(−1)i−n(ni​)f(i) 。

形式一证明 f(n)=∑i=0n(ni)∑j=0i(−1)i−j(ij)f(j)=∑i=0n∑j=0i(−1)i−j(ni)(ij)f(j)=∑j=0nf(j)∑i=jn(−1)i−j(ni)(ij)=∑j=0n(nj)f(j)∑i=jn(n−ji−j)(−1)i−j=∑j=0n(nj)f(j)∑t=0n−j(n−jt)(−1)t1n−j−t=∑j=0n(nj)f(j)(1−1)n−j\begin{aligned} f(n)&=\sum\limits_{i=0}^n{n\choose i}\sum\limits_{j=0}^i(-1)^{i-j}{i\choose j}f(j)\\&=\sum\limits_{i=0}^n\sum\limits_{j=0}^i(-1)^{i-j}{n\choose i}{i\choose j}f(j) \\&=\sum\limits_{j=0}^nf(j)\sum\limits_{i=j}^n(-1)^{i-j}{n\choose i}{i\choose j}\\&=\sum\limits_{j=0}^n{n\choose j}f(j)\sum\limits_{i=j}^n{n-j\choose i-j}(-1)^{i-j}\\ &=\sum\limits_{j=0}^n{n\choose j}f(j)\sum\limits_{t=0}^{n-j}{n-j\choose t}(-1)^t1^{n-j-t}\\ &=\sum\limits_{j=0}^n{n\choose j}f(j)(1-1)^{n-j} \end{aligned} f(n)​=i=0∑n​(in​)j=0∑i​(−1)i−j(ji​)f(j)=i=0∑n​j=0∑i​(−1)i−j(in​)(ji​)f(j)=j=0∑n​f(j)i=j∑n​(−1)i−j(in​)(ji​)=j=0∑n​(jn​)f(j)i=j∑n​(i−jn−j​)(−1)i−j=j=0∑n​(jn​)f(j)t=0∑n−j​(tn−j​)(−1)t1n−j−t=j=0∑n​(jn​)f(j)(1−1)n−j​ 当
n−j≠0n-j\neq 0n−j​=0 时,(1−1)n−j=0(1-1)^{n-j}=0(1−1)n−j=0

当 n−j=0n-j=0n−j=0 时,由于出现 000^000 ,而 000^000 没有任何意义,所以我们从组合角度出发,有 (n−jt)(−1)t=1{n-j\choose t}(-1)^{t}=1(tn−j​)(−1)t=1

故 : ∑t=0n−j(n−jt)(−1)t=[j=n]\displaystyle \sum\limits_{t=0}^{n-j}{n-j\choose t}(-1)^t=[j=n] t=0∑n−j​(tn−j​)(−1)t=[j=n]

即: f(n)=(nn)f(n)=f(n)f(n)={n\choose n}f(n)=f(n) f(n)=(nn​)f(n)=f(n)
二项式反演第一种形式得证 □\square□

%

形式二证明 f(n)=∑i=nm(in)∑j=im(−1)j−i(ji)f(j)=∑i=nm∑j=im(−1)j−i(in)(ji)f(j)=∑j=nmf(j)∑i=nj(−1)j−i(in)(ji)=∑j=nm(jn)f(j)∑i=nj(j−nj−i)(−1)j−i=∑j=nm(jn)f(j)∑t=0j−n(j−nt)(−1)t1j−n−t=∑j=nm(jn)f(j)(1−1)j−n=∑j=nm(jn)f(j)[j=n]=(nn)f(n)=f(n)\begin{aligned} f(n)&=\sum\limits_{i=n}^m{i\choose n}\sum\limits_{j=i}^m(-1)^{j-i}{j\choose i}f(j)\\ &=\sum\limits_{i=n}^m\sum\limits_{j=i}^m(-1)^{j-i}{i\choose n}{j\choose i}f(j)\\ &=\sum\limits_{j=n}^mf(j)\sum\limits_{i=n}^j(-1)^{j-i}{i\choose n}{j\choose i}\\ &=\sum\limits_{j=n}^m{j\choose n}f(j)\sum\limits_{i=n}^j{j-n\choose j-i}(-1)^{j-i}\\ &=\sum\limits_{j=n}^m{j\choose n}f(j)\sum\limits_{t=0}^{j-n}{j-n\choose t}(-1)^{t}1^{j-n-t}\\ &=\sum\limits_{j=n}^m{j\choose n}f(j)(1-1)^{j-n}\\ &=\sum\limits_{j=n}^m{j\choose n}f(j)[j=n]\\ &={n\choose n}f(n)\\ &=f(n) \end{aligned} f(n)​=i=n∑m​(ni​)j=i∑m​(−1)j−i(ij​)f(j)=i=n∑m​j=i∑m​(−1)j−i(ni​)(ij​)f(j)=j=n∑m​f(j)i=n∑j​(−1)j−i(ni​)(ij​)=j=n∑m​(nj​)f(j)i=n∑j​(j−ij−n​)(−1)j−i=j=n∑m​(nj​)f(j)t=0∑j−n​(tj−n​)(−1)t1j−n−t=j=n∑m​(nj​)f(j)(1−1)j−n=j=n∑m​(nj​)f(j)[j=n]=(nn​)f(n)=f(n)​
二项式反演第二种形式得证 □\square□


基本性质定理

性质44.1:f(n)=∑i=0nCnig(i)⟺\displaystyle f(n)=\sum_{i=0}^{n}C_{n}^{i}g(i) \Longleftrightarrowf(n)=i=0∑n​Cni​g(i)⟺g(n)=∑i=0n(−1)n−iCnif(i)\text g(n)=\sum_{i=0}^{n}(-1)^{n-i}C_{n}^{i}f(i)g(n)=∑i=0n​(−1)n−iCni​f(i)

性质44.2:f(n)=∑i=0n(−1)iCnig(i)⟺\displaystyle f(n)=\sum_{i=0}^{n}(-1)^{i}C_{n}^{i}g(i)\Longleftrightarrowf(n)=i=0∑n​(−1)iCni​g(i)⟺g(n)=∑i=0n(−1)iCnif(i)\text g(n)=\sum_{i=0}^{n}(-1)^{i}C_{n}^{i}f(i)g(n)=∑i=0n​(−1)iCni​f(i)

性质44.3:f(n)=∑i=n?Cing(i)⟺\displaystyle f(n)=\sum_{i=n}^{?}C_{i}^{n}\text g(i) \Longleftrightarrowf(n)=i=n∑?​Cin​g(i)⟺g(n)=∑i=n?(−1)i−nCinf(i)\text g(n)=\sum_{i=n}^{?}(-1)^{i-n}C_{i}^{n}f(i)g(n)=∑i=n?​(−1)i−nCin​f(i)(例题、例题)

性质44.4:f(n)=∑i=n?(−1)iCing(i)⟺\displaystyle f(n)=\sum_{i=n}^{?}(-1)^{i}C_{i}^{n}\text g(i)\Longleftrightarrowf(n)=i=n∑?​(−1)iCin​g(i)⟺g(n)=∑i=n?(−1)iCinf(i)\text g(n)=\sum_{i=n}^{?}(-1)^{i}C_{i}^{n}f(i)g(n)=∑i=n?​(−1)iCin​f(i)

性质44.5:f(n,m)=∑i=0n∑j=0mCniCmjg(i,j)⟺\displaystyle f(n,m)=\sum\limits_{i=0}^{n}\sum\limits_{j=0}^{m}C_{n}^{i}C_{m}^{j}g(i,j) \Longleftrightarrowf(n,m)=i=0∑n​j=0∑m​Cni​Cmj​g(i,j)⟺g(n,m)=∑i=0n∑j=0m(−1)n+m−i−jCniCmjf(i,j)g(n,m)=\sum\limits_{i=0}^{n}\sum\limits_{j=0}^{m}(-1)^{n+m-i-j}C_{n}^{i}C_{m}^{j}f(i,j)g(n,m)=i=0∑n​j=0∑m​(−1)n+m−i−jCni​Cmj​f(i,j)

性质44.6:f(n,m)=∑i=0n∑j=0m(−1)i+jCniCmjg(i,j)⟺\displaystyle f(n,m)=\sum\limits_{i=0}^{n}\sum\limits_{j=0}^{m}(-1)^{i+j}C_{n}^{i}C_{m}^{j}g(i,j) \Longleftrightarrowf(n,m)=i=0∑n​j=0∑m​(−1)i+jCni​Cmj​g(i,j)⟺g(n,m)=∑i=0n∑j=0m(−1)i+jCniCmjf(i,j)g(n,m)=\sum\limits_{i=0}^{n}\sum\limits_{j=0}^{m}(-1)^{i+j}C_{n}^{i}C_{m}^{j}f(i,j)g(n,m)=i=0∑n​j=0∑m​(−1)i+jCni​Cmj​f(i,j)

性质44.7:f(n,m)=∑i=n?∑j=m?CinCjmg(i,j)⟺\displaystyle f(n,m)=\sum\limits_{i=n}^{?}\sum\limits_{j=m}^{?}C_{i}^{n}C_{j}^{m}g(i,j) \Longleftrightarrowf(n,m)=i=n∑?​j=m∑?​Cin​Cjm​g(i,j)⟺g(n,m)=∑i=n?∑j=m?(−1)i+j−n−mCinCjmf(i,j)g(n,m)=\sum\limits_{i=n}^{?}\sum\limits_{j=m}^{?}(-1)^{i+j-n-m}C_{i}^{n}C_{j}^{m}f(i,j)g(n,m)=i=n∑?​j=m∑?​(−1)i+j−n−mCin​Cjm​f(i,j)(例题、例题)

性质44.8:f(n,m)=∑i=n?∑j=m?(−1)i+jCinCjmg(i,j)⟺\displaystyle f(n,m)=\sum\limits_{i=n}^{?}\sum\limits_{j=m}^{?}(-1)^{i+j}C_{i}^{n}C_{j}^{m}g(i,j) \Longleftrightarrowf(n,m)=i=n∑?​j=m∑?​(−1)i+jCin​Cjm​g(i,j)⟺g(n,m)=∑i=n?∑j=m?(−1)i+jCinCjmf(i,j)g(n,m)=\sum\limits_{i=n}^{?}\sum\limits_{j=m}^{?}(-1)^{i+j}C_{i}^{n}C_{j}^{m}f(i,j)g(n,m)=i=n∑?​j=m∑?​(−1)i+jCin​Cjm​f(i,j)


竞赛例题选讲

Problem A. 集合计数 ([BZOJ 2839])

一个有N个元素的集合有 2N2^N2N 个不同子集(包含空集),现在要在这 2N2^N2N 个集合中取出若干集合(至少一个),使得它们的交集的元素个数为 KKK,求取法的方案数,答案模1000000007。(是质数喔~)

1≤N≤106,0≤K≤N1≤N≤10^6,0≤K≤N1≤N≤106,0≤K≤N

Solution

设 f(i)f(i)f(i) 表示钦定交集元素为某 iii 个,子集的交集至少为这 iii 个元素的子集的方案数

显然有 f(i)=(ni)22n−i−1f(i)= {n \choose i}2^{2^{n-i}-1}f(i)=(in​)22n−i−1

即先钦定 iii 个必选的元素,所有子集至少包含该 iii 个元素, 剩余 n−in-in−i 个元素,这 n−in-in−i 个元素,每个元素对于每一个子集而言,可选可不选,故能组成的至少包含这 iii 个元素的子集方案数为 2n−i2^{n-i}2n−i 个,不允许存在空集,故一共是 2n−i−12^{n-i}-12n−i−1 个可用子集,选择若干子集求交集的时候,每个子集可选可不选,子集的选择方案数为 22n−i−12^{2^{n-i}-1}22n−i−1。

我们再设 g(i)\text g(i)g(i) 表示交集元素恰好为 iii 个的方案数,答案显然就是 g(k)g(k)g(k) ,则显然有
f(k)=(nk)(22n−k−1)=∑i=kn(ik)g(i)\begin{aligned}f(k)&={n\choose k}(2^{2^{n-k}}-1)&\\&=\sum\limits_{i=k}^n{i\choose k}\text g(i)\end{aligned} f(k)​=(kn​)(22n−k−1)=i=k∑n​(ki​)g(i)​
进行二项式反演显然有:

g(k)=∑i=kn(−1)i−k(ik)f(i)=∑i=kn(−1)i−k(ik)(ni)(22n−i−1)\begin{aligned}g(k)&=\sum\limits_{i=k}^n(-1)^{i-k}{i\choose k}f(i)&\\&=\sum\limits_{i=k}^n(-1)^{i-k}{i\choose k}{n\choose i}(2^{2^{n-i}}-1)\end{aligned} g(k)​=i=k∑n​(−1)i−k(ki​)f(i)=i=k∑n​(−1)i−k(ki​)(in​)(22n−i−1)​
预处理后计算即可。

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

Code

#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 7, mod = 1e9 + 7;int n, m, s, t, k, ans, a[N];
int fact[N], infact[N], inv[N], pow22[N];void pre_work(int n)
{inv[1] = fact[0] = infact[0] = 1;pow22[0] = 2;for (int i = 2; i <= n; ++ i) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;for (int i = 1; i <= n; ++ i) {fact[i] = 1ll * fact[i - 1] * i % mod;infact[i] = 1ll * infact[i - 1] * inv[i] % mod;pow22[i] = 1ll * pow22[i - 1] * pow22[i - 1] % mod;}
}int C(int n, int m)
{if(n == m) return 1;return 1ll * fact[n] * infact[n - m] % mod * infact[m] % mod;
}int main()
{pre_work(N - 7);scanf("%d%d", &n, &k);ans = 0;for (int i = k; i <= n; ++ i) {if((i - k) & 1) ans = (1ll * ans - 1ll * C(i, k) * C(n, i) % mod * (pow22[n - i] - 1 + mod) % mod + mod) % mod;else ans = (1ll * ans + 1ll * C(i, k) * C(n, i) % mod * (pow22[n - i] - 1 + mod) % mod) % mod;}cout << ans << endl;return 0;
}

0x45 斯特林反演

前置知识

这里先复习一下两类斯特林数与上升幂,下降幂之间的转换公式:

xn=∑i=0nS(n,i)xi‾xn=∑i=0n(−1)n−iS(n,i)xi‾xn‾=∑i=0n(−1)n−is(n,i)xixn‾=∑i=0ns(n,i)xi\begin{aligned} x^n&=\sum_{i=0}^{n}S(n,i)x^{\underline i}\\ x^n&=\sum_{i=0}^{n}(-1)^{n-i}S(n,i)x^{\overline i}\\ x^{\underline n}&=\sum_{i=0}^{n}(-1)^{n-i}s (n,i)x^i\\ x^{\overline n}&=\sum_{i=0}^{n}s (n,i)x^i \end{aligned}xnxnxn​xn​=i=0∑n​S(n,i)xi​=i=0∑n​(−1)n−iS(n,i)xi=i=0∑n​(−1)n−is(n,i)xi=i=0∑n​s(n,i)xi​

根据下降幂的公式:

xn=∑i=0nS(n,i)xi‾x^n=\sum_{i=0}^{n}S(n,i)x^{\underline i}xn=i=0∑n​S(n,i)xi​

我们根据上面的公式将其变成上升幂:

xn=∑i=0nS(n,i)(−1)i(−x)i‾x^n=\sum_{i=0}^{n}S(n,i)(-1)^i(-x)^{\overline i}xn=i=0∑n​S(n,i)(−1)i(−x)i

代入上升幂转第一类斯特林数的公式:

xn=∑i=0nS(n,i)(−1)i∑j=0is(i,j)(−x)jx^n=\sum\limits_{i=0}^{n}S(n,i)(-1)^i\sum\limits_{j=0}^{i}s(i,j)(-x)^jxn=i=0∑n​S(n,i)(−1)ij=0∑i​s(i,j)(−x)j

把 xxx 的幂提前,换一下求和符号:

xn=∑j=0nxj∑i=jnS(n,i)s(i,j)(−1)i−jx^n=\sum\limits_{j=0}^{n}x^j\sum\limits_{i=j}^nS(n,i)s(i,j)(-1)^{i-j}xn=j=0∑n​xji=j∑n​S(n,i)s(i,j)(−1)i−j

由于这里我们把 xxx 看成未知量,其他的都是已知量,所以我们可以把左右当作多项式,那么对比系数可得 反转公式

∑i=mnS(n,i)s(i,m)(−1)i−m=[m=n]\sum\limits_{i=m}^{n}S(n,i)s(i,m)(-1)^{i-m}=[m=n]i=m∑n​S(n,i)s(i,m)(−1)i−m=[m=n]

同理我们可以得出第二个反转公式

∑i=mns(n,i)S(i,m)(−1)i−m=[m=n]\sum\limits_{i=m}^{n}s(n,i)S(i,m)(-1)^{i-m}=[m=n]i=m∑n​s(n,i)S(i,m)(−1)i−m=[m=n]

注意:反转公式 −1−1−1 的指数也可以写成 n−in−in−i ,稍加分析可以发现 m=nm=nm=n 时成立, m≠nm≠nm​=n 时有两种情况,一种不变,另一种会将答案取相反数,但是由于结果为 000 所以不影响。

斯特林反演及其证明

了解了上面的前置知识以后,我们引出斯特林反演的公式

f(n)=∑i=0nS(n,i)g(i)⟺g(n)=∑i=0n(−1)n−is(n,i)f(i)f(n)=\sum_{i=0}^{n}S(n,i)\text g(i)\Longleftrightarrow \text g(n)=\sum_{i=0}^{n}(-1)^{n-i}s(n,i)f(i)f(n)=i=0∑n​S(n,i)g(i)⟺g(n)=i=0∑n​(−1)n−is(n,i)f(i)

考虑证明:


我们先写出一个 [i=n][i=n][i=n] 的形式:

g(n)=∑i=0n[i=n]g(i)\text g(n)=\sum\limits_{i=0}^{n}[i=n]\text g(i)g(n)=i=0∑n​[i=n]g(i)

我们再把斯特林数以及 [m=n][m=n][m=n] 的式子套进去,也就是上面的反转公式(注意 −1−1−1 的指数):

g(n)=∑i=0ng(i)∑j=in(−1)n−js1(n,j)s2(j,i)=∑j=0n(−1)n−js1(n,j)∑i=0js2(j,i)g(i)=∑i=0n(−1)n−is1(n,i)f(i)\begin{aligned} \text g(n)&=\sum_{i=0}^{n}\text g(i)\sum_{j=i}^{n}(-1)^{n-j}s_1(n,j)s_2(j,i)\\ &=\sum_{j=0}^{n}(-1)^{n-j}s_1(n,j)\sum_{i=0}^{j}s_2(j,i)\text g(i)\\ &=\sum_{i=0}^{n}(-1)^{n-i}s_1(n,i)f(i) \end{aligned}g(n)​=i=0∑n​g(i)j=i∑n​(−1)n−js1​(n,j)s2​(j,i)=j=0∑n​(−1)n−js1​(n,j)i=0∑j​s2​(j,i)g(i)=i=0∑n​(−1)n−is1​(n,i)f(i)​

综上所述,斯特林反演公式得证。□

当然由于反转公式的对称性,所以互换 sss 和 SSS 依然成立。


性质45.1:f(n)=∑i=0nSnig(i)⟺\displaystyle f(n)=\sum_{i=0}^{n} S_{n}^{i} \text g(i) \Longleftrightarrowf(n)=i=0∑n​Sni​g(i)⟺g(n)=∑i=0n(−1)n−isnig(i)\text g(n)=\sum_{i=0}^{n}(-1)^{n-i} s_{n}^{i} \text g(i)g(n)=∑i=0n​(−1)n−isni​g(i)

性质45.2:f(n)=∑i=0nsnig(i)⟺\displaystyle f(n)=\sum_{i=0}^{n}s_{n}^{i}\text g(i)\Longleftrightarrowf(n)=i=0∑n​sni​g(i)⟺g(n)=∑i=0n(−1)n−iSnif(i)\text g(n)=\sum_{i=0}^{n}(-1)^{n-i}S_{n}^{i}f(i)g(n)=∑i=0n​(−1)n−iSni​f(i)

性质45.3:f(n)=∑i=n?Sing(i)⟺\displaystyle f(n)=\sum_{i=n}^{?} S_{i}^{n} \text g(i) \Longleftrightarrowf(n)=i=n∑?​Sin​g(i)⟺g(n)=∑i=n?(−1)i−nsing(i)\text g(n)=\sum_{i=n}^{?}(-1)^{i-n} s_{i}^{n} \text g(i)g(n)=∑i=n?​(−1)i−nsin​g(i)

性质45.4:f(n)=∑i=n?sing(i)⟺\displaystyle f(n)=\sum_{i=n}^{?}s_{i}^{n}\text g(i)\Longleftrightarrowf(n)=i=n∑?​sin​g(i)⟺g(n)=∑i=n?(−1)i−nSinf(i)\text g(n)=\sum_{i=n}^{?}(-1)^{i-n}S_{i}^{n}f(i)g(n)=∑i=n?​(−1)i−nSin​f(i)


竞赛例题选讲

Problem A. 方阵([2018雅礼集训1-16])

给出一个 n×mn×mn×m 大小的矩形,每个位置可以填上 [1,c][1,c][1,c] 中的任意一个数,要求填好后任意两行互不等价且任意两列互不等价,两行或两列等价当且仅当对应位置完全相同,求方案数 。

n,m≤5000n,m≤5000n,m≤5000

Solution

%https://www.cnblogs.com/hchhch233/p/10016522.html

0x46 单位根反演

单位根反演

∀k,[n∣k]=1n∑i=0n−1ωnik\forall k,[n\mid k]=\frac{1}{n}\sum_{i=0}^{n-1}\omega_n^{ik} ∀k,[n∣k]=n1​i=0∑n−1​ωnik​

若 n∣kn\mid kn∣k ,显然有 ωnik=ω0=1\omega_n^{ik}=\omega^0=1ωnik​=ω0=1,故 1n∑i=0n−1ωnik=1\displaystyle \frac{1}{n}\sum_{i=0}^{n-1}\omega_n^{ik}=1n1​i=0∑n−1​ωnik​=1.

若 n∤kn\nmid kn∤k,1n∑i=0n−1ωnik=1nωnnk−ωn0ωnk−1=0\displaystyle \frac{1}{n}\sum_{i=0}^{n-1}\omega_n^{ik}=\displaystyle \frac{1}{n}\frac{\omega_n^{nk}-\omega_n^0}{\omega_n^k-1}=0n1​i=0∑n−1​ωnik​=n1​ωnk​−1ωnnk​−ωn0​​=0

故原式得证。

若需计算某个多项式的特定倍数的系数和,即 ∑i=0[nk][xik]f(x)\displaystyle \sum_{i=0}^{[\frac{n}{k}]}[x^{ik}]f(x)i=0∑[kn​]​[xik]f(x)

则有:

∑i=0[nk][xik]f(x)=∑i=0n[k∣i][xi]f(x)=∑i=0n[xi]f(x)1k∑j=0k−1ωkji=1k∑i=0nai∑j=0k−1ωkij=1k∑j=0k−1∑i=0nai(ωkj)i=1k∑j=0k−1f(ωkj)\begin{aligned} &\ \ \ \ \sum_{i=0}^{[\frac{n}{k}]}[x^{ik}]f(x)=\sum_{i=0}^n[k|i][x^i]f(x)\\ &=\sum_{i=0}^n [x^i]f(x)\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{ji}\\ &=\frac{1}{k}\sum_{i=0}^n a_i\sum_{j=0}^{k-1}\omega_{k}^{ij}\\ &=\frac{1}{k}\sum_{j=0}^{k-1}\sum_{i=0}^n a_i(\omega_k^j)^i\\ &=\frac{1}{k}\sum_{j=0}^{k-1}f(\omega_{k}^j) \end{aligned}​    i=0∑[kn​]​[xik]f(x)=i=0∑n​[k∣i][xi]f(x)=i=0∑n​[xi]f(x)k1​j=0∑k−1​ωkji​=k1​i=0∑n​ai​j=0∑k−1​ωkij​=k1​j=0∑k−1​i=0∑n​ai​(ωkj​)i=k1​j=0∑k−1​f(ωkj​)​


  • 基本性质定理

性质46.1.1:[n∣k]=∑i=0n−1wnikn\displaystyle [n|k]=\frac{\displaystyle \sum_{i=0}^{n-1}w_{n}^{ik}}{n}[n∣k]=ni=0∑n−1​wnik​​

性质46.1.2:[a=b]=∑i=0n−1wnaiwn−ibn(a,b<n)\displaystyle [a=b]=\frac{\displaystyle \sum_{i=0}^{n-1} w_{n}^{a i} w_{n}^{-i b}}{n}(a,b<n)[a=b]=ni=0∑n−1​wnai​wn−ib​​(a,b<n)

  • 推导结论

结论46.2.1:∑i=0nCnimia(imod4)=14∑j=03aj∑k=03w4−kj(mw4k+1)n\displaystyle \sum_{i=0}^{n}C_{n}^{i}m^{i}a_{(i\mod 4)}=\frac{1}{4}\sum_{j=0}^{3}a_{j} \sum_{k=0}^{3}w_{4}^{-kj}(mw_{4}^{k}+1)^{n}i=0∑n​Cni​mia(imod4)​=41​j=0∑3​aj​k=0∑3​w4−kj​(mw4k​+1)n(例题)

结论46.2.1:∑i=0nCnimi⌊ik⌋=\displaystyle \sum\limits_{i=0}^{n}C_{n}^{i}m^i\lfloor\frac{i}{k}\rfloor=i=0∑n​Cni​mi⌊ki​⌋=1k(nm(m⁣+⁣1)n−1−1k∑t=0k(mωkt+1)nf(t))\frac{1}{k}{\left(nm\ (m\!+\!1)^{n-1}-\frac{1}{k}{\sum\limits_{t=0}^{k}(m\omega_{k}^{t}+1)^{n}f(t)}\right)}k1​(nm (m+1)n−1−k1​t=0∑k​(mωkt​+1)nf(t))(例题)


竞赛例题选讲

%[https://www.cnblogs.com/cjjsb/p/11728892.html](https://www.cnblogs.com/cjjsb/p/11728892.html)

0x47 子集反演

说是子集反演,其实就是裸的容斥

基本性质定理

性质47.1:f(S)=∑T⊆Sg(T)⟺g(S)=∑T⊆S(−1)∣S∣−∣T∣f(T)\displaystyle f(S)=\sum_{T\subseteq S}g(T)\Longleftrightarrow g(S)=\sum_{T\subseteq S}(-1)^{|S|-|T|}f(T)f(S)=T⊆S∑​g(T)⟺g(S)=T⊆S∑​(−1)∣S∣−∣T∣f(T)(模板)

性质47.2:f(S)=∑T⊇Sg(T)⟺g(S)=∑T⊇S(−1)∣T∣−∣S∣f(T)\displaystyle f(S)=\sum_{T\supseteq S}g(T)\Longleftrightarrow g(S)=\sum_{T\supseteq S}(-1)^{|T|-|S|}f(T)f(S)=T⊇S∑​g(T)⟺g(S)=T⊇S∑​(−1)∣T∣−∣S∣f(T)

性质47.3:f(S)=∑T⊆Sg(T)⟺g(S)=∑T⊆Sμ(∣S∣−∣T∣)f(T)\displaystyle f(S)=\sum_{T\subseteq S}g(T)\Longleftrightarrow g(S)=\sum_{T\subseteq S}\mu(|S|-|T|)f(T)f(S)=T⊆S∑​g(T)⟺g(S)=T⊆S∑​μ(∣S∣−∣T∣)f(T)(μ(S)\mu(S)μ(S) 在 SSS 有重复元素时为 000,否则为 (−1)∣S∣(-1)^{|S|}(−1)∣S∣)

性质47.4:f(S)=∑T⊇Sg(T)⟺g(S)=∑T⊇Sμ(∣T∣−∣S∣)f(T)\displaystyle f(S)=\sum_{T\supseteq S}g(T)\Longleftrightarrow g(S)=\sum_{T\supseteq S}\mu(|T|-|S|)f(T)f(S)=T⊇S∑​g(T)⟺g(S)=T⊇S∑​μ(∣T∣−∣S∣)f(T)(μ(S)\mu(S)μ(S) 在 SSS 有重复元素时为 000,否则为 (−1)∣S∣(-1)^{|S|}(−1)∣S∣)


竞赛例题选讲

Problem A. 黑暗前的幻想乡 (Luogu P4336 [SHOI2016])

n≤17,P=109+7n\le 17, P = 10^9+7n≤17,P=109+7

Solution

题目就是要求由 n−1n-1n−1 个公司每个公司一条边建成的生成树的方案数。

显然求生成树的方案数,我们直接用矩阵树定理计算即可。

现在考虑满足 每个公司都只负责一条边的方案数 如何计算。

显然有:n≤17+计数问题=容斥n\le 17 + 计数问题 = \text{容斥}n≤17+计数问题=容斥

我们可以先用矩阵树定理计算 n−1n-1n−1 个公司包含的所有边集的生成树的个数,显然这里算出来的生成树,不一定 n−1n-1n−1 个公司都参与了建设,我们用容斥原理减去不合法的即可。

显然就是枚举有多少个公司没有参与建设,然后利用容斥原理奇加偶减,答案减去容斥原理计算出的结果,变成奇减偶加。

我们设 g(S)g(S)g(S)为最终的答案,即全集 SSS 全部被覆盖的情况的方案数。

f(S)f(S)f(S) 为公司恰好仅为 SSS 的方案。

显然有:

g(S)=∑T⊆Sf(T)g(S)=\sum\limits_{T\subseteq S}f(T)g(S)=T⊆S∑​f(T)

根据子集反演可得:

f(S)=∑T⊆S(−1)∣S∣−∣T∣g(T)f(S)=\sum\limits_{T\subseteq S}(-1)^{\left|S\right|-\left|T\right|}g(T)f(S)=T⊆S∑​(−1)∣S∣−∣T∣g(T)

即答案就是所有生成树的方案数,减去 111 个公司没有参与,由剩下的 n−2n-2n−2 个公司建成的生成树的个数,加上 222 个公司没有参与,由剩下的 n−3n-3n−3 个公司建成的生成树的个数,减去 333 个公司没有参与,由剩下的 n−4n-4n−4 个公司建成的生成树的个数 ⋯\cdots⋯

我们可以通过二进制枚举来枚举具体选择了那几个公司的边,处理出此时的基尔霍夫矩阵,然后直接利用矩阵树定理高斯消元 O(n3)O(n^3)O(n3) 计算代数余子式的行列式即可。

注意我们矩阵树定理计算的时候是可以处理重边的,所以如果一条边被多个公司覆盖,就把它当成重边即可,这样都当成重边算,最后减下来是没有重边的。

Time

O(2n×n3log⁡P)O(2^{n}\times n^3\log P)O(2n×n3logP)

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;const int N = 100 + 7, M = 1e5 + 7, mod = 1e9 + 7;int n, m[M], s, t, k, ans, a[N][N];
int siz[M];
int u[N][N], v[N][N];int qpow(int a, int b)
{int res = 1;while(b) {if(b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}int guass2(int n)// 辗转相除 = TLE
{int det = 1;for (int i = 2; i <= n; ++ i) {for (int j = i + 1; j <= n; ++ j) {while(a[j][i]) {int t = a[i][i] / a[j][i];for (int k = i; k <= n; ++ k)a[i][k] = (a[i][k] - t * a[j][k] + mod) % mod;swap(a[i], a[j]);det = -det;} }det = (det * a[i][i]) % mod;if(det == 0) return 0;}return (det + mod) % mod;
}int guass(int n)// 求逆元 = AC
{int det = 1;for (int i = 2; i <= n; ++ i) {for (int j = i; j <= n; ++ j) {if(a[i][j]) {swap(a[i], a[j]);if(i != j) det = mod - det;break;}}int inv = qpow(a[i][i], mod - 2);for (int j = i + 1; j <= n; ++ j) {if(a[j][i]) {int tmp = a[j][i] * inv % mod;for (int k = i; k <= n; ++ k) {a[j][k] = (a[j][k] - a[i][k] * tmp % mod + mod) % mod;}}}}for (int i = 2; i <= n; ++ i)det = det * a[i][i] % mod;return det;
}signed main()
{scanf("%lld", &n); for (int i = 1; i <= n - 1; ++ i) {scanf("%lld", &m[i]);for (int j = 1; j <= m[i]; ++ j) {scanf("%lld%lld", &u[i][j], &v[i][j]);int x = u[i][j], y = v[i][j];a[x][x] ++ ;a[y][y] ++ ;a[x][y] = (a[x][y] + mod - 1) % mod;a[y][x] = (a[y][x] + mod - 1) % mod;}} ans = guass(n);for (int i = 1; i <= (1 << (n - 1)) - 1; ++ i) {for (int j = 1; j <= n; ++ j) for (int k = 1; k <= n; ++ k) a[j][k] = 0;int cnt = 0;int tmp = i, j;for (j = 1; tmp; tmp >>= 1, ++ j) {if((tmp & 1) == 0) continue;cnt ++ ; for (int k = 1; k <= m[j]; ++ k) {int x = u[j][k], y = v[j][k];a[x][x] ++ ;a[y][y] ++ ;a[x][y] = (a[x][y] + mod - 1) % mod;a[y][x] = (a[y][x] + mod - 1) % mod;}}if(cnt == n - 1) continue;ans = (ans - ((((n - 1) - cnt) & 1) ? 1 : -1) * guass(n) + mod) % mod;}printf("%lld\n", ans);return 0;
}

0x48 最值反演 ( Min - Max 容斥)

基本性质定理

最值反演 —— Min - Max 容斥

设 min⁡\minmin 为集合最小值,max⁡\maxmax 为集合最大值

max⁡(S)=∑T⊆S(−1)∣T∣+1min⁡(T)min⁡(S)=∑T⊆S(−1)∣T∣+1max⁡(T)\max(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\min(T)\\\min(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\max(T)max(S)=T⊆S∑​(−1)∣T∣+1min(T)min(S)=T⊆S∑​(−1)∣T∣+1max(T)

证明:

记 S={ai}S=\{a_i\}S={ai​},其中对于 i<ji<ji<j 有 ai<aja_i<a_jai​<aj​
那么我们计算每一个 aia_iai​ 的贡献,有

∑T∈S(−1)∣T∣+1min⁡{T}=∑i=1nai∑j=0n−i(−1)j(n−ij)=∑i=1nai[n−i=0]=∑i=1nai[n=i]=an=max⁡{S}\begin{aligned}\sum_{T \in S}(-1)^{|T|+1} \min \{T\} &=\sum_{i=1}^{n} a_{i} \sum_{j=0}^{n-i}(-1)^{j}\left(\begin{array}{c}n-i \\j\end{array}\right) \\&=\sum_{i=1}^{n} a_{i}[n-i=0] \\&=\sum_{i=1}^{n} a_{i}[n=i] \\&=a_{n} \\&=\max \{S\}\end{aligned} T∈S∑​(−1)∣T∣+1min{T}​=i=1∑n​ai​j=0∑n−i​(−1)j(n−ij​)=i=1∑n​ai​[n−i=0]=i=1∑n​ai​[n=i]=an​=max{S}​

Min - Max 容斥在期望意义下也是成立的:,设 E(x)E(x)E(x) 表示元素 xxx 出现的期望操作次数,则:

E(max⁡(S))=∑T⊆S(−1)∣T∣−1E(min⁡(T))E(min⁡(S))=∑T⊆S(−1)∣T∣−1E(max⁡(T))E(\max(S))=\sum_{T \subseteq S}(-1)^{|T|-1}E(\min(T))\\ E(\min(S))=\sum_{T \subseteq S}(-1)^{|T|-1}E(\max(T)) E(max(S))=T⊆S∑​(−1)∣T∣−1E(min(T))E(min(S))=T⊆S∑​(−1)∣T∣−1E(max(T))

拓展 Min - Max 容斥

设 kthmax⁡(S)k^{th}\max(S)kthmax(S) 表示 S 的第 k 大元素, 则
kthmax⁡(S)=∑T⊆S(−1)∣T∣−k(∣T∣−1k−1)min⁡(T)k^{th}\max(S)=\sum_{T \subseteq S} (-1)^{|T|-k} {|T|-1 \choose k-1} \min(T) kthmax(S)=T⊆S∑​(−1)∣T∣−k(k−1∣T∣−1​)min(T)

证明同上,同样在期望意义下成立:

E(kthmax⁡(S))=∑T⊆S(−1)∣T∣−k(∣T∣−1k−1)E(min⁡(T))\displaystyle E(k^{th}\max(S))=\sum_{T\subseteq S}(-1)^{|T|-k}{|T|-1\choose k-1}E(\min(T))E(kthmax(S))=T⊆S∑​(−1)∣T∣−k(k−1∣T∣−1​)E(min(T))


性质48.1: max⁡(S)=∑T⊆S(−1)∣T∣+1min⁡(T)\displaystyle \max(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\min(T)max(S)=T⊆S∑​(−1)∣T∣+1min(T)
性质48.2: min⁡(S)=∑T⊆S(−1)∣T∣+1max⁡(T)\displaystyle \min(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\max(T)min(S)=T⊆S∑​(−1)∣T∣+1max(T)
性质48.3: E(max⁡(S))=∑T⊆S(−1)∣T∣−1E(min⁡(T))\displaystyle E(\max(S))=\sum_{T \subseteq S}(-1)^{|T|-1}E(\min(T))E(max(S))=T⊆S∑​(−1)∣T∣−1E(min(T))
性质48.4: E(min⁡(S))=∑T⊆S(−1)∣T∣−1E(max⁡(T))\displaystyle E(\min(S))=\sum_{T \subseteq S}(-1)^{|T|-1}E(\max(T))E(min(S))=T⊆S∑​(−1)∣T∣−1E(max(T))
性质48.5: kthmax⁡(S)=∑T⊆S(−1)∣T∣−k(∣T∣−1k−1)min⁡(T)\displaystyle k^{th}\max(S)=\sum_{T \subseteq S} (-1)^{|T|-k} {|T|-1 \choose k-1} \min(T)kthmax(S)=T⊆S∑​(−1)∣T∣−k(k−1∣T∣−1​)min(T)
性质48.6: E(kthmax⁡(S))=∑T⊆S(−1)∣T∣−k(∣T∣−1k−1)E(min⁡(T))\displaystyle E(k^{th}\max(S))=\sum_{T\subseteq S}(-1)^{|T|-k}{|T|-1\choose k-1}E(\min(T))E(kthmax(S))=T⊆S∑​(−1)∣T∣−k(k−1∣T∣−1​)E(min(T))

Problem A

有 N(1≤N≤20)N(1\le N \le 20)N(1≤N≤20)张卡片,每包中含有这些卡片的概率为 p1,p2,⋯pNp_1,p_2,\cdots p_Np1​,p2​,⋯pN​。每包至多一张卡片,可能没有卡片。求需要买多少包才能拿到所有的 NNN 张卡片,求次数的期望。

Solution

对于此题,我们想要求出所有卡片集合 S 中最晚出现的卡片的期望,就转化为计算 S 的所有子集中最早出现的期望

点集中最早出现的元素的期望是 min ,最晚出现的元素的期望是 max ;全部出现的期望就是最晚出现的元素的期望。

对于一个集合T,显然出现一张卡片的期望为1∑i∈Tpi\displaystyle \cfrac{1}{\sum_{i \in T} p_{i}}∑i∈T​pi​1​

Code

const int N = 23, M = 1048576 + 3;
int n, V, cnt[M];
double ans, p[N], Min[M];
int main() {while (~scanf("%d", &n)) {V = (1 << n) - 1, ans = 0;for (int i = 1; i <= n; ++i)scanf("%lf", &p[i]);for (int s = 1; s <= V; ++s) {Min[s] = 0, cnt[s] = cnt[s >> 1] + (s & 1);for (Re i = 1; i <= n; ++i)if (s & (1 << i - 1))Min[s] += p[i];Min[s] = 1.0 / Min[s];}for (int t = 1; t <= V; ++t)ans += (cnt[t] & 1) ? Min[t] : -Min[t];printf("%lf\n", ans);}
}

Problem B. 按位或(Luogu P3175 [HAOI2015])

刚开始你有一个数字 000,每一秒钟你会随机选择一个 [0,2n−1][0,2^n-1][0,2n−1] 的数字,与你手上的数字进行按位或。选择数字 iii 的概率是 pip_ipi​ 。保证 0≤pi≤10\leq p_i \leq 10≤pi​≤1,∑pi=1\sum p_i=1∑pi​=1 。问期望多少秒后,你手上的数字变成 2n−12^n-12n−1。

Solution

分析题目,我们每次选择的数是在 [0,2n−1][0,2^n-1][0,2n−1] 的数,进行按位或运算,显然无论如何选择,手里的数都不会大于 2n−12^n-12n−1。我们希望最后手里的数变为 2n−12^n-12n−1,即一个 nnn 位二进制数 xxx 中所有 nnn 位全部变成 111,因此我们可以将问题抽象成,有一个 nnn 位二进制数 xxx,开始 nnn 位上全是 000,我们每次选择一个数,可以使得 xxx 发生变化,最后 xxx 的所有位全部变为 111 的期望选择次数(时间)。

然后因为选择数字 iii 的概率为 pip_ipi​,我们每次选择数 iii,使得该二进制数发生一些变化,直到所有二进制数全部变为 111,显然我们可以联想到一个类似的问题模型:有 n≤20n\le 20n≤20 种牌,每种牌无限张,得到第 iii 种牌的概率为 pip_ipi​,问每张牌均至少拥有一张的期望购买次数(时间)。即 HDU4336 Card Collector,我们发现抽象出来问题模型之后,两个问题的模型几乎一模一样!

我们回想 HDU4336 Card Collector 是怎么解决的, Min - Max 容斥!

我们设 aia_iai​ 为得到卡片 iii 的期望时间,集合 S={ai}S=\{a_i\}S={ai​}。显然 max⁡{S}\max\{S\}max{S} 为得到最后一张卡片的期望时间(此时我们已经得到了所有的卡片,游戏结束),则 min⁡{S}\min\{S\}min{S} 为得到第一张卡片的期望时间。

显然有 Min - Max 容斥:

max⁡(S)=∑T⊆S(−1)∣T∣+1min⁡(T)min⁡(S)=∑T⊆S(−1)∣T∣+1max⁡(T)\max(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\min(T)\\\min(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\max(T)max(S)=T⊆S∑​(−1)∣T∣+1min(T)min(S)=T⊆S∑​(−1)∣T∣+1max(T)

我们只需要直接爆搜计算集合 SSS 的所有子集 TTT 的 min⁡(T)=1∑i∈Tpi\min(T)=\frac 1{\sum\limits_{i\in T}p_i}min(T)=i∈T∑​pi​1​ 即可在 O(2n)O(2^n)O(2n) 的时间复杂度下求得 max⁡(S)\max(S)max(S),即为答案。

显然两个题目的模型是一模一样的,我们考虑使用 Min - Max 容斥解决本题。

类似的,我们设 aka_kak​ 为二进制数 xxx 的第 kkk 位变为 111 的期望时间,集合 S={ai}S=\{a_i\}S={ai​},显然这里的 SSS 为全集,也就是二进制数 xxx 的全部 nnn 位,SSS 的子集 TTT,表示某几位,也就是二进制数 xxx 的 y≤ny\le ny≤n 位。

显然 max⁡{S}\max\{S\}max{S} 为二进制数 xxx 的所有位均为 111 所有的期望时间, min⁡{S}\min\{S\}min{S} 为二进制数 xxx 第一次有位数变为 111 的期望时间。

max⁡(S)=∑T⊆S(−1)∣T∣+1min⁡(T)\max(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\min(T)max(S)=T⊆S∑​(−1)∣T∣+1min(T)

同样的,我们只需要计算集合 SSS 的所有子集 TTT 的 min⁡(T)\min(T)min(T) 即可。

显然根据期望公式有:

min⁡(T)=∑i=1+∞i×P(min⁡(T)=i)\min(T)=\sum\limits^{+\infty}_{i=1}i\times P(\min(T)=i)min(T)=i=1∑+∞​i×P(min(T)=i)

其中 P(min⁡(T)=i)P(\min(T)=i)P(min(T)=i) 表示在第 iii 秒,集合 TTT 中第一次出现了 111 的概率,这也就意味着前 i−1i−1i−1 秒内,每一秒,集合 TTT 中均没有出现 111,即集合 TTT 在全集 SSS 的补集 WWW 中出现了 111(W=∁ST,W∩T=∅,W+T=SW=\complement_ST,W\cap T=\varnothing,W+T=SW=∁S​T,W∩T=∅,W+T=S,显然 W=Sxor TW=S\ \text{xor}\ TW=S xor T,因为这里代表的是二进制数)。设每一秒为事件 AAA,显然有 P(A)=∑w⊂WP(w)P(A)=\sum\limits_{w\subset W}P(w)P(A)=w⊂W∑​P(w) ,其中 P(w)P(w)P(w) 表示出现的 111 是在集合 www 中的概率。

第 iii 秒,集合 TTT 第一次出现 111,显然概率为 1−P(A)=1−∑w⊂WP(w)1-P(A)=1-\sum\limits_{w\subset W}P(w)1−P(A)=1−w⊂W∑​P(w)。

显然为几何概型,期望为:
E(min⁡(T))=1P=11−∑w⊂WP(w),W=∁ST\begin{aligned}E(\min(T))&={\dfrac{1}{P}}&\\&=\dfrac{1}{1-\displaystyle\sum\limits_{w\subset W}P(w)},W=\complement_ST\end{aligned}E(min(T))​=P1​=1−w⊂W∑​P(w)1​,W=∁S​T​

也就是说我们只需要计算出每个集合的子集和概率之和 ∑w⊂WP(w)\displaystyle\sum\limits_{w\subset W}P(w)w⊂W∑​P(w) 即可利用 Min - Max 容斥在 O(2n)O(2^n)O(2n) 的复杂度下计算出答案。

那么要怎么算呢?

显然如果直接枚举子集计算的话需要 O(3n)O(3^n)O(3n),n≤20n\le 20n≤20,肯定要炸,所以考虑优化。

我们知道 FMT 计算按位或卷积的时候我们执行了这样一个 O(nlog⁡n)O(n\log n)O(nlogn) 的过程:

定义 FMT(f)n=∑i⊆nfi\text{FMT}(f)_n=\sum_{i\subseteq n}f_iFMT(f)n​=∑i⊆n​fi​

FMT(a)n×FMT(b)n=∑i⊆nai∑j⊆nbj=∑k⊆n∑i∪j=kaibj=FMT(c)n\begin{aligned} &\text{FMT}(a)_n\times \text{FMT}(b)_n\\ &{=\sum_{i\subseteq n}a_i\sum_{j\subseteq n}b_j}\\ &{=\sum_{k\subseteq n}\sum_{i∪j=k}a_ib_j}\\ &{=\text{FMT}(c)_n} \end{aligned}​FMT(a)n​×FMT(b)n​=i⊆n∑​ai​j⊆n∑​bj​=k⊆n∑​i∪j=k∑​ai​bj​=FMT(c)n​​

好嘛,FMT 就是枚举子集…

即:序列经历过一次 FMT 按位或变换之后得到的新的序列就是原序列的子集和形式!

因此我们可以直接利用一次 FMT 在 O(mlog⁡m),m=2nO(m\log m),m=2^{n}O(mlogm),m=2n 的复杂度下计算出所有的 P(w)=∑w⊂WP(w)P(w)=\displaystyle\sum\limits_{w\subset W}P(w)P(w)=w⊂W∑​P(w),然后利用 Min - Max 容斥在 O(2n)O(2^n)O(2n) 的复杂度下计算出答案即可。

Code

// Problem: P3175 [HAOI2015]按位或
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3175
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h>using namespace std;
const int N = 3e6 + 7;int n, m, s, t, k, a[N];
double ans;
double p[N];
int cnt[N];void FMT_OR(double *f, int n, double x = 1.0)
{for (int o = 2; o <= n; o <<= 1) {for (int i = 0, k = o >> 1; i <= n; i += o) {for (int j = 0; j < k; ++ j) {f[i + j + k] = f[i + j] * x + f[i + j + k];}}}
} int main()
{scanf("%d", &n);int S = (1 << n) - 1; int limit = 1;while(limit <= S) limit <<= 1;for (int i = 0; i <= S; ++ i) scanf("%lf", &p[i]);FMT_OR(p, limit); for (int i = 1; i <= S; ++ i) cnt[i] = cnt[i >> 1] + (i & 1);ans = 0;for (int i = 1; i <= S; ++ i) {int SminusT = S ^ i;if(1 - p[SminusT] < 1e-8) return puts("INF"), 0;ans += 1.0 / (1.0 - p[SminusT]) * (cnt[i] & 1 ? 1 : -1);}printf("%.10f\n", ans);return 0;
}

Problem C. 重返现世 (Luogu P4707)

为了打开返回现世的大门,Yopilla 需要制作开启大门的钥匙。Yopilla 所在的迷失大陆有 nnn 种原料,只需要集齐任意 kkk 种,就可以开始制作。

Yopilla 来到了迷失大陆的核心地域。每个单位时间,这片地域就会随机生成一种原料。每种原料被生成的概率是不同的,第 iii 种原料被生成的概率是 pim\cfrac{p_i}{m}mpi​​ 。如果 Yopilla 没有这种原料,那么就可以进行收集。

Yopilla 急于知道,他收集到任意 kkk 种原料的期望时间,答案对 998244353998244353998244353 取模。

Solution

https://www.luogu.com.cn/blog/Sooke/solution-p4707

0x49 拉格朗日反演

基本性质定理

对于两个多式 F(x),G(x)F(x),G(x)F(x),G(x),两个多项式都是常数项均为 000 且 111 次项不为 000,如果有 F(G(x))=xF(G(x))=xF(G(x))=x ,我们称 F,GF,GF,G 互为复合逆,同时一定有 G(F(x))=xG(F(x))=xG(F(x))=x ,即可称 G(x)=F−1(x),F(x)=G−1(x)G(x)=F^{-1}(x),F(x)=G^{-1}(x)G(x)=F−1(x),F(x)=G−1(x) 。

在这种情况下,拉格朗日反演

[xn]F(x)=1n[x−1](1G(x))n=1n[xn−1](xG(x))n\displaystyle [x^n]F(x)=\frac{1}{n}[x^{-1}](\frac{1}{G(x)})^n=\frac{1}{n}[x^{n-1}](\frac{x}{G(x)})^n [xn]F(x)=n1​[x−1](G(x)1​)n=n1​[xn−1](G(x)x​)n

扩展拉格朗日反演

[xn]H(F(x))=1n[x−1]H′(x)(1G(x))n=1n[xn−1]H′(x)(xG(x))n[x^n]H(F(x))=\frac{1}{n}[x^{-1}]H'(x)(\frac{1}{G(x)})^n=\frac{1}{n}[x^{n-1}]H'(x)(\frac{x}{G(x)})^n [xn]H(F(x))=n1​[x−1]H′(x)(G(x)1​)n=n1​[xn−1]H′(x)(G(x)x​)n

Problem A. 大朋友和多叉树(BZOJ 3684)

我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树。对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为 111 的结点是叶子结点;对于任一点权大于 111 的结点 uuu,uuu 的孩子数目 deg[u] 属于集合 DDD ,且 uuu 的点权等于这些孩子结点的点权之和。
给出一个整数 sss ,你能求出根节点权值为 sss 的神犇多叉树的个数吗?请参照样例以更好的理解什么样的两棵多叉树会被视为不同的。
我们只需要知道答案关于 950009857950009857950009857 (453×221+1453\times 2^{21}+1453×221+1,一个质数)取模后的值。

1≤m<s≤105,2≤d[i]≤s1\le m<s\le 10^5, 2\le d[i]\le s1≤m<s≤105,2≤d[i]≤s

Solution

显然计数问题,我们可以写出二叉树的个数的生成函数为:

H(x)=x+∏i∈DHi(x)⇒H(x)−∏i∈DHi(x)=xH(x)=x+\prod_{i\in D}H^i(x)\\\Rightarrow H(x)-\prod_{i\in D}H^i(x)=x H(x)=x+i∈D∏​Hi(x)⇒H(x)−i∈D∏​Hi(x)=x

令 F(x)=H(x)F(x)=H(x)F(x)=H(x),G(x)=x−∏i∈DxiG(x)=x-\prod_{i\in D}x^iG(x)=x−∏i∈D​xi,显然有 G(F(x))=xG(F(x))=xG(F(x))=x

因此我们就可以进行拉格朗日反演:

[xn]F(x)=1n[x−1]1G(x)n[x^n]F(x)=\frac{1}{n}[x^{-1}]\frac{1}{G(x)^n} [xn]F(x)=n1​[x−1]G(x)n1​

显然直接辅以多项式全家桶暴力计算即可在 O(nlog⁡n)O(n\log n)O(nlogn) 的时间复杂度下求出 T(s)T(s)T(s) 即为答案。

0x4A 反演常用技巧

反演往往是通过一系列和式变换,将一个无法承受的时间复杂度优化到一个可以接收的时间复杂度下,

技巧4A.1 :无关项提前

∑i=1n∑j=1mnaibj=n∑i=1nai∑j=1mbj\sum_{i=1}^n\sum_{j=1}^mna_ib_j=n\sum_{i=1}^na_i\sum_{j=1}^mb_j i=1∑n​j=1∑m​nai​bj​=ni=1∑n​ai​j=1∑m​bj​

技巧4A.2 :交换枚举顺序

∑i=1nai∑j=1mbj=∑j=1mbj∑i=1nai\sum_{i=1}^na_i\sum_{j=1}^mb_j=\sum_{j=1}^mb_j\sum_{i=1}^na_i i=1∑n​ai​j=1∑m​bj​=j=1∑m​bj​i=1∑n​ai​

∑i=1nai∑d∣ibd=∑d=1nbd∑i=1⌊nd⌋aid\sum_{i=1}^na_i\sum_{d|i}b_d=\sum_{d=1}^nb_d\sum_{i=1}^{\lfloor\frac nd\rfloor}a_{id} i=1∑n​ai​d∣i∑​bd​=d=1∑n​bd​i=1∑⌊dn​⌋​aid​

这样可以将枚举的约数变成枚举倍数。

技巧4A.3 :暴力破解法

无从下手的时候,多一个暴力枚举判断,多一重枚举,构造出判断式,尝试构造 ε=[n=1]\varepsilon=[n=1]ε=[n=1] 进行反演。

∑i=1n∑j=1mf(gcd⁡(i,j))=∑d=1min(n,m)∑i=1n∑j=1mf(d)[gcd⁡(i,j)=d]=∑d=1min(n,m)f(d)∑i=1n∑j=1m[gcd⁡(i,j)=d]⋯\begin{aligned}&\ \ \ \ \ \ \ \ \sum_{i=1}^n\sum_{j=1}^mf(\gcd(i,j))&\\& =\sum_{d=1}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^mf(d)[\gcd(i,j)=d]&\\& =\sum_{d=1}^{min(n,m)}f(d)\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=d]&\\& \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \cdots \end{aligned} ​        i=1∑n​j=1∑m​f(gcd(i,j))=d=1∑min(n,m)​i=1∑n​j=1∑m​f(d)[gcd(i,j)=d]=d=1∑min(n,m)​f(d)i=1∑n​j=1∑m​[gcd(i,j)=d]                              ⋯​​

技巧4A.4 :减少未知数
∑p∣k∑d=1⌊np⌋μ(d)⌊npd⌋⌊mpd⌋\displaystyle \sum_{p|k}\sum_{d=1}^{\lfloor\frac{n}{p}\rfloor}\mu(d)\lfloor\frac{n}{pd}\rfloor\lfloor\frac{m}{pd}\rfloor p∣k∑​d=1∑⌊pn​⌋​μ(d)⌊pdn​⌋⌊pdm​⌋
可以令 k=pdk=pdk=pd(尽量减少未知数,减少枚举)
∑p∣k∑d=1⌊np⌋μ(kp)⌊nk⌋⌊mk⌋\displaystyle \sum_{p|k}\sum_{d=1}^{\lfloor\frac{n}{p}\rfloor}\mu(\frac{k}{p})\lfloor\frac{n}{k}\rfloor\lfloor\frac{m}{k}\rfloor p∣k∑​d=1∑⌊pn​⌋​μ(pk​)⌊kn​⌋⌊km​⌋

技巧4A.5:狄利克雷卷积优化

尽力拼凑成积性函数卷积的形式

∑d=1nd3∑k=1⌊nd⌋μ(k)k2(∑i=1⌊ndk⌋i)2=∑T=1nT2μ(Td)d(∑i=1⌊ndk⌋i)2=∑T=1nT2φ(Td×d)(∑i=1⌊ndk⌋i)2=∑T=1nT2φ(T)∑i=1⌊ndk⌋i3\begin{aligned}&\ \ \ \ \ \sum_{d=1}^nd^3\sum_{k=1}^{\left\lfloor\frac n d\right\rfloor}\mu(k)k^2(\sum_{i=1}^{\left\lfloor\frac n {dk}\right\rfloor}i)^2&\\&=\sum_{T=1}^{n}T^2\mu(\frac T d)d(\sum_{i=1}^{\left\lfloor\frac n {dk}\right\rfloor}i)^2&\\&=\sum_{T=1}^{n}T^2\varphi(\frac T d \times d)(\sum_{i=1}^{\left\lfloor\frac n {dk}\right\rfloor}i)^2&\\&=\sum_{T=1}^{n}T^2\varphi(T)\sum_{i=1}^{\left\lfloor\frac n {dk}\right\rfloor}i^3\end{aligned} ​     d=1∑n​d3k=1∑⌊dn​⌋​μ(k)k2(i=1∑⌊dkn​⌋​i)2=T=1∑n​T2μ(dT​)d(i=1∑⌊dkn​⌋​i)2=T=1∑n​T2φ(dT​×d)(i=1∑⌊dkn​⌋​i)2=T=1∑n​T2φ(T)i=1∑⌊dkn​⌋​i3​​

技巧4A.6:前缀和公式

1+2+3+⋯+(n−1)=12n2−12n=n(n−1)212+22+32+⋯+(n−1)2=13n3−12n2+16n=n(n−1)(2n−1)613+23+33+⋯+(n−1)3=14n4−12n3+14n2=n2(n−1)2414+24+34+⋯+(n−1)4=15n5−12n4+13n3−n30=n(n−1)(2n−1)(3n2−3n−1)3015+25+35+⋯+(n−1)5=16n6−12n5+512n4−112n2=n2(n−1)2(2n2−2n−1)12\begin{aligned}&1+2+3+\cdots+(n-1)\ \ \ \ \ \ =\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \frac 1 2n^2-\frac 1 2n \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ = \frac{n(n-1)} 2&\\&1^2+2^2+3^2+\cdots+(n-1)^2=\ \ \ \ \ \ \ \ \ \ \ \frac 1 3n^3-\frac 1 2 {n^2} +\frac 1 6n \ \ \ \ \ \ \ = \frac{n(n-1)(2n-1)} 6&\\&1^3+2^3+3^3+\cdots+(n-1)^3=\ \ \ \ \ \ \ \ \ \frac 1 4n^4-\frac 1 2 {n^3} +\frac 1 4n^2\ \ \ \ \ \ \ = \frac{n^2(n-1)^2} 4&\\&1^4+2^4+3^4+\cdots+(n-1)^4=\ \ \ \ \frac 1 5 n^5-\frac 1 2n^4+\frac 1 3 n^3-\frac n {30} \ \ =\frac{n(n-1)(2n-1)(3n^2-3n-1)}{30}&\\&1^5+2^5+3^5+\cdots+(n-1)^5=\frac 1 6n^6-\frac 1 2 n^5+\frac 5 {12}n^4-\frac 1 {12}n^2=\frac{n^2(n-1)^2(2n^2-2n-1)}{12}\end{aligned} ​1+2+3+⋯+(n−1)      =               21​n2−21​n               =2n(n−1)​12+22+32+⋯+(n−1)2=           31​n3−21​n2+61​n       =6n(n−1)(2n−1)​13+23+33+⋯+(n−1)3=         41​n4−21​n3+41​n2       =4n2(n−1)2​14+24+34+⋯+(n−1)4=    51​n5−21​n4+31​n3−30n​  =30n(n−1)(2n−1)(3n2−3n−1)​15+25+35+⋯+(n−1)5=61​n6−21​n5+125​n4−121​n2=12n2(n−1)2(2n2−2n−1)​​​

证明

规定 C(n,k)C(n,k)C(n,k) 表示从 nnn 个数中取 kkk 个的组合数。

2n+1=1+C(n+1,1)1n+C(n+1,2)1n−1+C(n+1,3)1n−2+⋯+C(n+1,n+1)2^{n+1}=1+C(n+1,1)1^n+C(n+1,2)1^{n-1}+C(n+1,3)1^{n-2}+\cdots+C(n+1,n+1)2n+1=1+C(n+1,1)1n+C(n+1,2)1n−1+C(n+1,3)1n−2+⋯+C(n+1,n+1)
3n+1=2n+1+C(n+1,1)2n+C(n+1,2)2n−1+c(n+1,3)2n−2+⋯+c(n+1,n+1)3^{n+1}=2^{n+1}+C(n+1,1)2^n+C(n+1,2)2^{n-1}+c(n+1,3)2^{n-2}+\cdots+c(n+1,n+1)3n+1=2n+1+C(n+1,1)2n+C(n+1,2)2n−1+c(n+1,3)2n−2+⋯+c(n+1,n+1)

(n+1)n+1=nn+1+C(n+1,1)nn+C(n+2,2)nn−1+⋯+C(n+1,n+1)(n+1)^{n+1}=n^{n+1}+C(n+1,1)n^n+C(n+2,2)n^{n-1}+\cdots+C(n+1,n+1)(n+1)n+1=nn+1+C(n+1,1)nn+C(n+2,2)nn−1+⋯+C(n+1,n+1)
上面 nnn 个式子相加
(n+1)n+1=1+(n+1)(1n+2n+...+nn)+C(n+2,2)(1n−1+2n−1+...+nn−1)+...+C(n+1,n)(1+2+3+...+n)+n(n+1)^{n+1}=1+(n+1)(1^n+2^n+...+n^n)+C(n+2,2)(1^{n-1}+2^{n-1}+...+n^{n-1})+...+C(n+1,n)(1+2+3+...+n)+n(n+1)n+1=1+(n+1)(1n+2n+...+nn)+C(n+2,2)(1n−1+2n−1+...+nn−1)+...+C(n+1,n)(1+2+3+...+n)+n
整理得
1n+2n+⋯+nn=(n+1)n−1n+1−(1n+1)(C(n+2,2)(1n−1+2n−1+..+nn−1)+...+C(n+1,n)(1+2+3+⋯+n)+n)1^n+2^n+\cdots+n^n=(n+1)^n-\frac 1 {n+1}-(\frac 1 {n+1})(C(n+2,2)(1^{n-1}+2^{n-1}+..+n^{n-1})+...+C(n+1,n)(1+2+3+\cdots+n)+n)1n+2n+⋯+nn=(n+1)n−n+11​−(n+11​)(C(n+2,2)(1n−1+2n−1+..+nn−1)+...+C(n+1,n)(1+2+3+⋯+n)+n)
我们知道 111 次的前缀和为: 1+2+⋯+n=n(1+n)21+2+\cdots+n=\cfrac {n(1+n)} 21+2+⋯+n=2n(1+n)​
因此我们就可以递推得到 222次,333 次,乃至 nnn 次前缀和公式

0x4B. Dirichlet 前缀和

0x4B.1 Dirichlet 前缀和

Template Problem Dirichlet 前缀和 (P5495)

给定一个长度为 nnn 的数列 a1,a2,a3,…,ana_1,a_2,a_3,\dots,a_na1​,a2​,a3​,…,an​ 。

现在你要求出一个长度为 nnn 的数列 b1,b2,b3,…,bnb_1,b_2,b_3,\dots,b_nb1​,b2​,b3​,…,bn​ ,满足

bd=∑i∣daib_d=\sum_{i|d}a_ibd​=i∣d∑​ai​

Solution

如果我们直接枚举倍数的话显然可以做到 O(∑i=1n⌊ni⌋)=O(nlog⁡n)\displaystyle O(\sum_{i=1}^n\left\lfloor\cfrac n i\right\rfloor)=O(n\log n)O(i=1∑n​⌊in​⌋)=O(nlogn) ,考虑优化。

根据唯一分解定理,我们可以设 i=∏pdαd,j=∏pdβd\displaystyle i=\prod p_d^{\alpha_d},j=\prod p_d^{\beta_d}i=∏pdαd​​,j=∏pdβd​​ ,则 aia_iai​ 贡献到 bjb_jbj​ 当且仅当 ∀d,αd≤βd\forall d,\alpha_d\leq \beta_d∀d,αd​≤βd​。

发现这个实际上就是一个关于质因子分解后的指数的高维前缀和(例如FMT),即每个数字会被它除以所有质因子的那个数转移过来,所有的质因子构成了一组正交基,核心代码:

    for(int i = 1; i <= cnt && primes[i] <= n; ++ i) for(int j = 1; j * primes[i] <= n; ++ j) a[j * primes[i]] += a[j];

显然时间复杂度同埃氏筛:O(nlog⁡log⁡n)O(n\log \log n)O(nloglogn)

Code

#define uint unsigned int
uint seed;
inline uint getnext() {seed ^= seed << 13;seed ^= seed >> 17;seed ^= seed << 5;return seed;
}
uint a[N], b[N];
uint ans;
int n, m;
bool vis[N];
int primes[N], cnt;
void get_primes(int n)
{for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) primes[ ++ cnt] = i;for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) break;}}
}
int main()
{get_primes(N - 1);scanf("%d%u", &n, &seed);for(int i = 1; i <= n; ++ i) a[i] = getnext();for(int i = 1; i <= cnt && primes[i] <= n; ++ i) for(int j = 1; j * primes[i] <= n; ++ j) a[j * primes[i]] += a[j];   ans = a[1];for(int i = 2; i <= n; ++ i) ans ^= a[i];printf("%u\n", ans);return 0;
}

0x4B.2 Dirichlet 后缀和

b[i]=∑i∣da[d]b[i] = \sum_{i|d} a[d]b[i]=i∣d∑​a[d]


我们这里是从一个数字本身 转移到 这个数字除以所有质因子的数。

    for(int i = 1; i <= cnt && primes[i] <= n; ++ i) for(int j = n / primes[i]; j ; -- j) a[j] += a[j * primes[i]];

0x4B.2 倒推 Dirichlet 前缀和

b[i]=∑d∣ia[d]b[i] = \sum_{d|i} a[d]b[i]=d∣i∑​a[d]

这里是我们知道数组 bbb ,求数组 aaa

    for(int i = cnt; i ; -- i) for(int j = n / primes[i]; j ; -- j) a[j * primes[i]] -= a[j];

0x4B.3 倒推 Dirichlet 后缀和

b[i]=∑i∣da[d]b[i] = \sum_{i|d} a[d]b[i]=i∣d∑​a[d]

同上,我们知道数组 bbb ,求数组 aaa

    for(int i = cnt; i ; -- i) for(int j = 1; j * primes[i] <= n; ++ j) a[j] -= a[j * primes[i]];

  1. 本小节部分内容来源于二项式反演及其应用@GXZlegend ↩︎

《算法竞赛中的初等数论》(四)正文 0x40反演(ACM / OI / MO)(十五万字符数论书)相关推荐

  1. 《算法竞赛中的初等数论》(一)正文 0x00整除、0x10 整除相关(ACM / OI / MO)(十五万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

  2. 《算法竞赛中的初等数论》(五)正文 0x50筛法(ACM / OI / MO)(十五万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

  3. 《算法竞赛中的初等数论》(三)正文 0x30 积性函数(ACM / OI / MO)(十五万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

  4. 《算法竞赛中的初等数论》(二)正文 0x20同余(ACM / OI / MO)(十五万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

  5. 《算法竞赛中的初等数论》(六)正文 0x60 原根(ACM / OI / MO)(二十万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

  6. 【更新完毕】《算法竞赛中的初等数论》(ACM / OI / MO)前言、后记、目录索引(十五万字符的数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 <算法竞赛中的初等数论>的全部内容的 Portable Document Format 版 ...

  7. 我的所有优质博客全部开源啦(我自己原创的《ACM模板》《算法全家桶》《算法竞赛中的初等数论》 PDF免费下载)

    你好呀ヾ(≧▽≦*)o 我是繁凡さん 这两年来我写了很多长篇文章,主要涉及数据结构,算法,程序设计竞赛,数学,计算几何等方面的内容: <数据结构>C语言版(清华严蔚敏考研版) 全书知识梳理 ...

  8. 成为计算几何master之路——记算法竞赛中常用的计几算法及思想

    文章目录 成为计算几何MASTER(FAKE)之路 1 引言 1.1 精度 1.2 剖分 1.3 层次化设计 2 点,向量和线 2.1 点积和叉积 2.2 线段(直线) 2.2.1 点在线段上判定 2 ...

  9. 算法竞赛中的时间复杂度选择——以最大连续和问题为例

    最大连续和问题 最大连续和问题.给出一个长度为nn的序列 A1,A2,-,AnA1, A2,-, An,求最大连续和.换句话说,要求找到1≤i≤j≤n1≤i≤j≤n,使得Ai+Ai+1+...+AjA ...

最新文章

  1. make for arm
  2. matlab字符衔接,matlab字符串连接(多个字符串)的经验,matlab字符串
  3. (转)Response.Redirect 打开新窗口的两种方法
  4. 数据结构与算法(C++)– 堆排(Heap Sort)
  5. Boost:双图bimap与lambda表达式的测试程序
  6. SMG12232A2标准图形点阵型液晶显示模块的演示程序[C51编程语言]
  7. linux 端口qos,linux的qos机制 - cgroup篇 (2)
  8. php在线读取pdf文件大小_PDF转WORD在线转换器哪家强?
  9. 史上最简单的玻尔兹曼机模型讲解
  10. ssm框架整合_框架整合战斗压缩粮篇SpringCloud+SpringBoot+SSM
  11. astc贴图格式是什么意思_SP多象限UV贴图的使用方法!
  12. 夺旗赛 CTF 六大方向基础工具简介集合(MISC,WEB,Crypto,Reverse,Pwn,Mobile)
  13. minist数据集训练与测试
  14. 利用FFT成功实现拓扑识别(五)--关于频谱泄露
  15. 实现 8086 汇编编译器(一)——基本框架
  16. 作为初学者,第一次用div+css编写淘宝静态首屏
  17. 文献笔记:Contrast-Phys: Unsupervised Video-based Remote Physiological Measurement viaSpatiotemporal Con
  18. 升降压电路的工作原理
  19. ios版本 线控 Android,iOS 耳机线控
  20. python云计算主要是干嘛的_阿里巴巴python云计算是干什么的

热门文章

  1. 图像去马赛克:双线性插值VS高质量线性插值
  2. 人脸识别:insightface自定义数据集制作 | 附练手数据集
  3. 链表问题15——将搜索二叉树转换成双向链表
  4. React 深入系列3:Props 和 State
  5. Gonet2 游戏server框架解析之gRPC提高(5)
  6. 2012-4-2 通过MdiParent设置窗体最前
  7. DevOps与持续交付实践
  8. ARM Linux (S3C6410架构/2.6.35内核)的内存映射(三)
  9. Nginx+Tomcat动静分离搭建
  10. 【转】Linux世界驰骋——文件系统和设备管理