3 月做题记录
\(\text{2025/3/26}\)
Luogu P3643 [APIO2016] 划艇
值域区间有经典套路,把它变成左闭右开的,端点扔进去离散化,然后考虑每对相邻端点所对应的值域段。设第 \(i\) 段的值域段为 \([l_i,r_i)\)。
考虑 DP。令 \(f_{i,j}\) 表示考虑前 \(i\) 所学校,第 \(i\) 所学校派出的划艇数量 \(cnt\in [l_j,r_j)\)。若 \([l_j,r_j)\not\subseteq [a_i,b_i)\),则 \(f_{i,j}=0\)。我们枚举最大的 \(k\) 使得它派出的划艇数量和 \(i\) 不在同一个值域段内,那么 \([k+1,i]\) 中的学校要么不派出划艇,要么划艇数量在 \([l_j,r_j)\) 内。设其中有 \(c\) 个学校 \(p\) 满足 \([l_j,r_j)\subseteq [a_p,b_p)\),即 \(c\) 个学校的划艇数量可以落在 \([l_j,r_j)\) 上,那么这部分的方案数相当于填 \(c\) 个数,满足非零数严格单增且落在 \([l_j,r_j)\) 上。枚举 \(0\) 的个数 \(t\),设 \(len_j=r_j-l_j\),容易得到方案数为
很显然的范德蒙德卷积的形式,因此这个式子等于 \(\binom{c+len_j}{c}\)。然后我们再枚举第 \(k\) 所学校所在值域段 \(p\),容易列出转移方程:
注意我们令 \(f_{i,0}\) 表示第 \(i\) 所学校不派出划艇的方案数。暴力转移时间复杂度 \(\mathcal{O}(n^4)\),无法承受。注意到 \(c\) 和 \(p\) 无关,可以提出来,变成
第二层求和显然可以直接前缀和优化掉。至于组合数和 \(c\) 的计算,我们倒序枚举 \(k\),则每次 \(k\leftarrow k-1\) 时,\(c\) 至多增加 \(1\),而我们有
于是我们线性递推预处理逆元,组合数就可以 \(\mathcal{O}(1)\) 递推了。时间复杂度 \(\mathcal{O}(n^3)\)。
Luogu P5591 小猪佩奇学数学
对于下整除有经典的 \(\left\lfloor\frac{i}{k}\right\rfloor=\frac{i-i\bmod{k}}{k}\),于是原式等于
把括号拆掉,分成两部分考虑。
-
\(\sum_{i=0}^n\binom{n}{i}ip^i\):由 \(\binom{n}{i}=\frac{n}{i}\binom{n-1}{i-1}\),得 \(i\binom{n}{i}=n\binom{n-1}{i-1}\),因此该式子等于 \(np\sum_{i=0}^n\binom{n-1}{i-1}p^{i-1}=np(p+1)^{n-1}\)。
-
\(\sum_{i=0}^n\binom{n}{i}(i\bmod{k})p^i\):套用单位根反演:
\[\begin{align*} & \sum_{i=0}^n\binom{n}{i}(i\bmod{k})p^i \\ = & \sum_{i=0}^n\binom{n}{i}p^i\sum_{j=0}^{k-1}j[i\equiv j\pmod{k}] \\ = & \frac{1}{k}\sum_{i=0}^n\binom{n}{i}p^i\sum_{j=0}^{k-1}j\sum_{x=0}^{k-1}\omega_k^{(i-j)x} \end{align*} \]考虑配出二项式定理的形式,变换求和顺序,得到
\[\begin{align*} & \frac{1}{k}\sum_{i=0}^n\binom{n}{i}p^i\sum_{j=0}^{k-1}j\sum_{x=0}^{k-1}\omega_k^{(i-j)x} \\ =&\frac{1}{k}\sum_{j=0}^{k-1}j\sum_{x=0}^{k-1}\omega_k^{-jx}\sum_{i=0}^n\binom{n}{i}\left(p\omega_k^{x}\right)^i \\ =&\frac{1}{k}\sum_{j=0}^{k-1}j\sum_{x=0}^{k-1}\omega_k^{-jx}\left(p\omega_k^{x}+1\right)^n \end{align*} \]再次变换求和顺序,得到
\[\begin{align*} &\frac{1}{k}\sum_{j=0}^{k-1}j\sum_{x=0}^{k-1}\omega_k^{-jx}\left(p\omega_k^{x}+1\right)^n\\ =&\frac{1}{k}\sum_{x=0}^{k-1}\left(p\omega_k^{x}+1\right)^n\sum_{j=0}^{k-1}j\left(\omega_k^{-x}\right)^j \end{align*} \]第二个求和是形如 \(S=\sum_{j=0}^{k-1}ja^j\) 的式子,且 \(a^k=1\)。考虑化简,我们对其进行错位相减,得
\[\begin{align*} &aS-S\\ =&\sum_{j=0}^{k-1}ja^{j+1}-\sum_{j=0}^{k-1}ja^j\\ =&\sum_{j=1}^{k}(j-1)a^j-\sum_{j=0}^{k-1}ja^j\\ =&(k-1)a^k-\sum_{j=1}^{k-1}a^j\\ =&k-1-\frac{a(1-a^{k-1})}{1-a}\\ =&k \end{align*} \]因此当 \(a\neq 1\) 时,\(S=k\),当 \(a=1\) 时,由等差数列求和公式知 \(S=\frac{k(k-1)}{2}\)。
根据上述过程计算即可,时间复杂度 \(\mathcal{O}(k\log{n})\)。
\(\text{2025/3/27}\)
Luogu P4035 [JSOI2008] 球形空间产生器
一个坐标对应一个方程,相邻两条方程相减可以消去高次项,对这 \(n\) 条方程 \(\mathcal{O}(n^3)\) 高斯消元求解即可。
Luogu P3232 [HNOI2013] 游走
令 \(f_u\) 表示点 \(u\) 被经过的期望次数,于是
可以 \(\mathcal{O}(n^3)\) 高斯消元求解。然后对于一条边 \((u,v)\),走过它的期望是 \(u\) 和 \(v\) 走过它的期望之和,即 \(\frac{f_u}{deg_u}+\frac{f_v}{deg_v}\)。于是对所有边按这个期望排序直接贪心即可。
\(\text{2025/3/29}\)
Luogu P4151 [WC2011] 最大XOR和路径
首先对于一棵树,任意一条从 \(x\) 走回到 \(x\) 的路径的异或和必然为 \(0\),因为考虑某条边 \((u,v)\),钦定 \(u\) 离 \(x\) 更近,那么这条边在奇数次被经过时必然是 \(u\) 走到 \(v\),偶数次被经过时必然是 \(v\) 走到 \(u\),显然 \(v\) 走到 \(x\) 的路径必须经过 \(u\),因此每条边都必然被经过偶数次。
对于任意一条 \(1\) 到 \(n\) 的路径,我们显然可以选出它的一个边的子集满足这个子集是一个 \(1\) 到 \(n\) 的链,其他部分则由环和非环边组成,我们不考虑复杂环,因为它只是简单环的线性组合,那么非环边必然会被走偶数次,因此这条路径的异或和等于这条链和这些环的异或和。而两条 \(1\) 到 \(n\) 的链构成一个环,所以我们可以给一条链异或上一个环变成另一条链。综上我们得出,\(1\) 到 \(n\) 的所有路径可以由某一条 \(1\) 到 \(n\) 的链和所有简单环表出。
但是简单环也有很多,我们无法全部搜出来。这里给出另一条结论:考虑原图的任意一颗生成树 \(T\),每一条非树边 \((u,v)\) 和 \(T\) 上 \(u\) 和 \(v\) 之间的路径构成一个环,我们把它称作这条非树边对应的环,那么原图中所有简单环可以由所有非树边对应的 \(m-n+1\) 个环表出。证明可以直接给出构造,对于任意一个简单环,考虑上面的每条非树边,我们都异或上它对应的简单环,显然异或完后这个简单环变成了 \(T\) 上一条某个点回到某个点的路径,根据前面的结论,这个路径异或和为 \(0\),于是这样就构造出了任意一个简单环的表示方法。
于是我们 dfs 出一个生成树 \(T\),取 \(T\) 上 \(1\) 到 \(n\) 的路径作为随意选择的一条链,然后对 \(m-n+1\) 个简单环建出线性基,直接求最大异或和即可。时间复杂度 \(\mathcal{O}(m\log{V})\)。
Luogu P4839 P 哥的桶
线段树维护线性基,单点插入时暴力对根到叶子的路径上的线性基插入即可。时间复杂度 \(\mathcal{O}(n\log{m}\log^2V)\)。
Luogu P3292 [SCOI2016] 幸运数字
倍增预处理线性基即可。视 \(n,q\) 同阶,时间复杂度 \(\mathcal{O}(n\log{n}\log^2{V})\)。注意线性基合并具有可重复贡献性,可以像 ST 表一样把 \(u\) 到 \(\operatorname{lca}(u,v)\) 的路径拆成两条相交路径的线性基的并,\(v\) 同理,询问复杂度可以去掉一个倍增的 \(\log{n}\)。
Luogu P5556 圣剑护符
考虑向线性基 \(B\) 中插入一个数 \(x\) 的过程,如果插入失败,说明 \(B\) 中必然存在子集的异或和为 \(x\),否则 \(B\) 中的 \(2^{|B|}\) 个子集对应的异或和互不相同,必然无法找到两个子集异或和相同。因此,能找到两个子集异或和相同的充要条件是存在数插入失败。但把路径上的点全部提出来暴力插入线性基还是会爆炸。又注意到线性基最多插入成功 \(\log{V}\) 次,因此长度 \(>\log{V}\) 的路径必然会插入失败,然后对于长度 \(\leq\log{V}\) 的路径暴力插入就可以接受了。
于是我们维护好属性值即可,要支持树链异或,考虑树上差分,转化成单点异或,查询子树异或和,在 DFS 序上建 BIT 维护异或和即可。视 \(n,q\) 同阶,时间复杂度 \(\mathcal{O}(n\log^3{V})\)。
LibreOJ #114 k 大异或和
从大到小遍历 \(p_i\),倒序枚举 \(j=i-1\sim 0\),若 \(p_i\) 的第 \(j\) 位为 \(1\) 就令 \(p_i\leftarrow p_i\oplus p_j\)。这样子就可以 \(\mathcal{O}(\log^2{V})\) 重构线性基,使得此时线性基 \(B\) 中任意两个元素的按位与结果为 \(0\),即 \(B\) 中元素的 \(1\) 位互不相交。然后考虑 \(k\) 的二进制表示,若 \(k\) 的第 \(i\) 位为 \(1\) 就给答案异或上 \(B\) 中第 \(i+1\) 小的元素。实现注意特判掉 \(k\geq 2^{|B|}\),并且如果 \(n\neq |B|\),\(0\) 也可以被表出,此时要令 \(k\leftarrow k-1\)。视 \(n,m\) 同阶,时间复杂度 \(\mathcal{O}(n\log{V})\)。
Luogu P4869 albus就是要第一个出场
我们指出,对于含 \(n\) 个数的可重集 \(S\),考虑其线性基 \(B\),则 \(S\) 的所有子集异或和有 \(2^{|B|}\) 种本质不同的数,每个数出现 \(2^{n-|B|}\) 次。
证明:向 \(B\) 中插入数时,有 \(k\) 个数插入成功,有 \(n-k\) 个数插入失败。我们只需证明,对于每个 \(B\) 能表出的数 \(x\),选择插入失败的数集的任意子集,都有对应方案选择插入成功的数集的子集,使得这两个子集的异或和为 \(x\)。设 \(B\) 中将 \(x\) 表出的子集为 \(T\),\(R=B\backslash T\),从插入失败的数集中选出的子集异或和为 \(v\)。首先显然 \(v\) 能由 \(B\) 表出,设将 \(v\) 表出的子集为 \(V\),我们对其情况进行分类讨论:
- 若 \(V\subseteq R\),在 \(B\) 中选择 \(T\cup V\) 即可。
- 若 \(V\subseteq T\),在 \(B\) 中选择 \(T\backslash V\) 即可。
- 若 \(V\) 既不是 \(R\) 的子集也不是 \(T\) 的子集,我们结合上面两种做法,把 \(V\) 拆成 \(V_1\subseteq R\) 和 \(V_2\subseteq T\),满足 \(V_1\cup V_2=V,V_1\cap V_2=\varnothing\),在 \(B\) 中选择 \(V_1\cup (T\backslash V_2)\) 即可。
因此对于每个 \(B\) 能表出的数 \(x\),插入失败的数集的 \(2^{n-|B|}\) 个子集中的任何一个都能从插入成功的数集中选择对应数集表示出 \(x\)。证毕。
接下来我们只需求出给定的数 \(x\) 在 \(B\) 的子集异或和中的排名 \(rk\),那么 \(2^{n-|B|}rk+1\) 就是它在原可重集的子集异或和中的排名了。我们遍历 \(x\) 的二进制 \(1\) 位就能确定它在 \(B\) 中的表出方案,若 \(p_i\) 在表出的子集中就令 \(rk\leftarrow rk+2^i\),其中 \(p_i\) 表示 \(B\) 中第 \(i\) 小的数。这样就能求出 \(rk\) 了。时间复杂度 \(\mathcal{O}(n\log{V})\)。
\(\text{2025/3/30}\)
Codeforces 2092C Asuna and the Mosquitoes
先特判掉全部同奇偶的情况,答案为 \(\max_{i=1}^n\{a_i\}\)。
接下来,设 \(a\) 中奇数个数为 \(k\),元素和为 \(s\),我们指出,答案就是 \(s-k+1\)。
证明:注意到每次操作完奇数集合大小不变,最优情况下奇数集合中只有 \(k-1\) 个 \(1\) 和 \(1\) 个 \(s-k+1\),偶数集合中全部是 \(0\),因此答案 \(\leq s-k+1\)。接下来我们尝试给出一组操作方案。首先,我们任意选择一个奇数 \(a_i\),把所有偶数加到上面去,得到了一个形如 \(a_i+2k\) 的奇数和若干个 \(0\)。然后对于剩下的 \(k-1\) 个奇数,选择其中一个,将其和某一个 \(0\) 放在一起操作,那么这个奇数就会被减 \(1\) 变成偶数,又可以被加到 \(a_i+2k\) 上去。对每个奇数都做这样的操作,显然最终可以得到 \(s-k+1\) 和 \(k-1\) 个 \(1\)。证毕。
Luogu P10704 救赎(Redemption)
首先我们指出:
证明:令 \(\text{LHS}=k\),这等价于
给 \(\frac{m}{a_i}\) 加上下取整不等式依然成立。证毕。
令 \(f(x)=\sum_{j=1}^n\left\lfloor\frac{x}{a_j}\right\rfloor\),于是原式变为
考虑如何快速计算 \(f(x)\)。考虑数论分块,令 \(cnt_{l,r}=\sum_{i=1}^n[l\leq a_i\leq r]\),那就变成了
对 \(a\) 排序后二分计算 \(cnt\),可以 \(\mathcal{O}(\sqrt{x}\log{n})\) 计算 \(f(x)\)。考虑优化,注意到 \(l-1,r\) 都是形如 \(\left\lfloor\frac{m}{i}\right\rfloor\) 的数,对所有 \(\mathcal{O}(\sqrt{m})\) 个端点计算前缀 \(cnt\) 即可。这样计算 \(f(x)\) 就是 \(\mathcal{O}(\sqrt{m}\log{n})-\mathcal{O}(\sqrt{x})\) 的。
外层对 \(\left\lfloor\frac{m}{a_i}\right\rfloor\) 记忆化,最多有 \(2\sqrt{m}\) 个点值,看似时间复杂度是 \(\mathcal{O}(m)\) 的,实际上是 \(\mathcal{O}(m^\frac{3}{4})\) 的。
证明:考察形如 \(\left\lfloor\frac{m}{i}\right\rfloor\) 的式子。当 \(i>\sqrt{m}\) 时,\(\left\lfloor\frac{m}{i}\right\rfloor\leq\sqrt{m}\),因此单次计算就是 \(\mathcal{O}(m^\frac{1}{4})\) 的;当 \(i\leq \sqrt{m}\) 时,总时间复杂度为
证毕。
综上,总时间复杂度为 \(\mathcal{O}(n\log{n}+m^\frac{3}{4})\)。
可撤销并查集
用栈维护历史状态。此时路径压缩损坏并查集的结构,不能使用,用启发式合并/按秩合并保证复杂度即可。
Luogu P5787 二分图 /【模板】线段树分治
线段树分治用于离线解决一类问题,形如:
- 操作只在某个时间段内有效。
- 询问某个时间点所有操作的贡献。
- 操作难以支持删除,但支持撤销。
我们在时间轴上建立线段树,对每个区间建一个 vector,把每个操作的时间段扔到线段树上分成 \(\log\) 个极长区间,把该操作加入这些极长区间的 vector 中。计算答案时,自顶而下遍历整颗线段树,对于每个节点,执行其 vector 中的操作,到达叶子节点时统计贡献,回溯时撤销操作。
对本题而言,可以用扩展域并查集维护二染色,然后支持一下可撤销就行了。时间复杂度 \(\mathcal{O}(m\log{n}\log{k})\)。
Luogu P5524 [Ynoi2012] NOIP2015 充满了希望
先不考虑操作 \(1\),对每个位置 \(x\) 维护最近一次被操作 \(2\) 覆盖的时间戳 \(t_x\),那么询问 \(x\) 就能造成 \(t_x\) 对应覆盖的值的贡献。考虑上操作 \(1\) 也很简单,\(\operatorname{swap}(t_x,t_y)\) 即可。用线段树容易计算每个在 \(i\) 时刻发生的询问操作对应的 \(t_i\) 及其答案 \(v\)。那么考虑所有可能造成贡献的 \((t_i,v)\) 对,当且仅当 \(l\leq t_i\leq i\leq r\) 时能造成 \(v\) 的贡献,简单二维数点即可。视 \(n,m,q\) 同阶,时间复杂度 \(\mathcal{O}(n\log{n})\)。

浙公网安备 33010602011771号