2024 年五月做题记录
CF1821F Timber
假如我已经知道了有哪些点放了树,如何判定这个点集是否合法?
这个显然,从左往右贪心,能往左倒就往左倒。
令这样得到的区间分别是 \([l_1, r_1], \cdots, [l_m,r_m]\),那么我们换个角度,通过计数这些区间的方案数来计数点集的方案数。
若 \(r_i\ge l_{i+1}-k\),那么 \(p_{i+1}\) 就只有一种方案,否则就有两种。
由于有 \(r_i=l_i+k\),改变描述形式:
对于所有满足 \(l_i - l_{i - 1} > k\) 的序列 \(l_1, \cdots, l_m\),求 \(\sum 2^{m-cnt}\)。
\(cnt\) 为 \(l_i - k > l_{i-1} + k\) 的 \(l\) 的个数。
\(l'_i \gets l_i - (i - 1)k\)。
对于所有序列 \(l'\),求 \(\sum 2^{m-cnt}\),其中 \(cnt\) 为 \(l_i-k>l_{i-1}\) 的 \(i\) 的个数(\(l'_m\le n - mk + k\))。
不妨计数 \(l_i-k\le l_{i-1}\) 的个数。
~~钦定至少有 \(x\) 个 \(i\) 满足 \(l_i-k\le l_{i-1}\),这个方案数为 ~~
rnm 好难。
钦定至少有 \(x\) 个 \(i\) 满足 \(l_i-k>l_{i-1}\),方案数为 我不想算这个**玩意了直接查看 zxx 题解吧
CF1730E Maximums and Minimums
枚举最小值 \(mn\) 与最大值 \(mx\)。
对于最大值,有 $l\in $ 一段区间,\(r \in\) 一段区间的限制。
对于最小值,同样有这种限制。
每次把这种限制的区间交起来就可以得到最后区间 \(l,r\) 的限制。
……稍等。并没有保证给出的是一个排列。
先枚举最大值,最小值的个数最多为 \(d(n)\)。
最大值已经限定了 \(l\) 和 \(r\) 都在一个区间之内。我们可以在 \(l\) 和 \(r\) 的区间内找到 \(mn\)。
然后经过一定的预处理和分讨就做完了。来锻炼一下耐心 😃
[ABC327G] Many Good Tuple Problems
把 \(X\) 按照值分成两个集合 \(A,B\),则 \((S_i, T_i)\) 必定有 \(S_i\in A, T_i\in B\)。
换而言之,把 \((S_i, T_i)\) 看做边,则形成一个二分图,没有奇环。
假设你现在已经确定了序列 \(M\) 生成的二分图(有 \(a\) 条边),如何求 \(M\) 的数量?
容斥可以 \(\mathcal{O}(a)\) 求。
如何求有 \(a\) 条边的二分图数量?随便做。
其实随便做不了。大致想了想然后看了眼题解,差不多。
一个联通的二分图,只有两种染色方案。
CF1630E Expected Components
CC = Connected Components.
题目中本质不同的定义为“不能经过旋转使得每一项都相等”。
不妨将所有本质相同的串丢在一起,称为等价类。
假设一个环有 \(d\) 的周期,它所在的等价类里就应当有 \(d\) 个长得不一样的环。
算上与它相同的环(\(\prod cnt_i!\)),它的贡献就应当是 \(\frac{\operatorname{cnt(CC)}}{\prod cnt_i!\times d}\)。这里对于所有环计数(个数为 \(n!\))。
枚举周期 \(d\)。\(\operatorname{cnt(CC)} = d\times\) 单个周期的连通块数。\(\prod cnt_i!\) 可以留到最后除。
所以我们最终需要对所有环计数 \(\sum \operatorname{cnt(CC)}\)。
对于每一个值,求 \(a_i=v\) 的连通块的期望个数。枚举这个期望个数,做一个组合数就做完了。
有 \(E(ans)=\frac{\sum{ \texttt{连通块个数} }}{\texttt{总方案数}}\)。
假设一个排列有 \(d\) 的周期,那么就有 \(d\) 个和它长的不一样,但是仍与它循环同构的排列。它的连通块数对答案的贡献就要除以 \(d\)。
枚举 \(d\)。总连通块数可以有单个周期连通块个数 \(\times d\) 来计算。
现在不需要管是不是循环同构了,只需要保证长得不一样就行。
单个周期连通块个数的总和,是由每个颜色构成的连通块个数加起来的。
先假装这不是一个环,再减去首尾相连时多算的一个环即可。
复杂度实际上是 \(\sigma_1(n)\)。
感谢良心出题人提供的良心样例。
AGC038E Gachapon
答案为 \(E(\max(\{i\ \texttt{出现}\ B_i\ \texttt{次的时间}\}))\)。
使用 \(\min-\max\) 容斥,答案为
\(\sum_{T\in \{1,2,\cdots,n\}} E(\min(\{i\ \texttt{出现}\ B_i\ \texttt{次的时间}\}))\times (-1)^{|T| + 1}\)。
如果只是这样的话,容易把在 \(T\) 内部和外部的点搞混,所以我们假装每次取必定取到 \(T\) 内部的点并将答案乘上 \(\frac{\sum A_i}{\sum_{i\in T} A_i}\)。
\(E(x)=\sum\limits_{i=1}^{+\infin} P(x\ge i)\)。
即 \(\sum\limits_{i=0}^{+\infin} P(x>i)\),在 \(i\) 轮后没有一个 \(T\) 内的点出现了 \(B\) 次的概率之和。
那么就有
\(E=\sum \prod (\frac{A_i}{\sum_{i\in T} A_i})^{c_i}\times \frac{k!}{\prod c_i!}\)。
那么直接 dp,维护 \(k\) 和 \(\sum A_i\) 即可。
时间复杂度 \(\mathcal{O}(.)\)。
[USACO23FEB] Problem Setting P
把这一列题在审核的过程抽象化,每个时刻 \(m\) 个裁判都处在两个状态之一:\(0(E), 1(H)\)。
则我们可以把这些裁判的状态压缩成一个 \(2^m\) 的二进制数。
每次加入一个新题,新的题目对应的状态必定是原先状态的超集。
那么把维持集合不变的都压成一步,状压 dp 即可。
设 \(f_i\) 为最后状态为 \(i\) 的方案数,\(cnt_i\) 为 [数据删除],则有
\(f_i=(1 + \sum_{j\subset i} f_j) cnt_i\)。
答案即为 \(\sum f_i\)。
很遗憾,这个算法的复杂度是 \(\mathcal{O}(3^n)\) 的。
考虑优化。以下内容参考第一篇题解
-
I. cdq 分治
先做出 \(0\sim 2^{n-1}-1\)(同时做出 \(f\) 和 \(f\) 的高维前缀和)
然后将贡献计入 \(2^n, 2^{n+1}-1\),做它的 \(f\) 和高位前缀和。
最后计算 \(0\sim 2^n - 1\) 的高维前缀和
已实现。 -
II. dp
设 \(f_{i, j}\) 为从第 \(i\) 位开始和 \(j\) 相同,第 \(0\sim i-1\) 位是 \(j\) 的子集的 \(f\) 的和。
动态维护即可。
Illumination
先不带 \(q\) 次查询地解决问题。
容斥,枚举 \(T\),计算 \(T\) 中的点都不被覆盖的方案数。
我会 \(\mathcal{O}(n2^m)\)!
事实上,我们可以把整个数轴切成若干段,对于每个 \(j\) 预处理出 \((l_i-p_j)\) 的前缀积来 \(\mathcal{O}(m)\) 计算。
那假如加了一个点,怎么办呢。
这个点对于答案的贡献是 \(f-p_j\),枚举 \(j\),如果对这个点造成贡献的是 \(j\),那么可以写成一个二维前缀和形式。
然而在我写到这里的时候 两年前的 zxx 已经过了这题了。/bx
不条理狂诗曲
考虑分治。现在分治区间是 \([L, R]\),则我们要计算
\(\sum_{l\in [L,mid],r\in (mid,R]} f(l,r)\)。
设 \(p_i\) 为强制不取 \(mid\) 时 \(f(i,mid)\) 的值,\(q'_i\) 为强制取 \(mid\) 时 \(f(i, mid)\) 的值。
设 \(w_i\) 为强制不取 \(mid+1\) 时 \(f(mid+1,i)\) 的值,\(v'_i\) 为强制取 \(mid + 1\) 时 \(f(mid + 1, i)\) 的值。
则 \(f(l,r)=\max\{p_l+v'_r, p_l+w_r, q'_l+w_r\}\)。
令 \(q_i=\max(q'_i, p_i), v_i=\max(v'_i, w_i)\)。
则 \(f(l, r)=\max(p_l+v_r, q_l+w_r)\)。
有 \(q_l\ge p_l, v_r\ge w_r\)。因此我们枚举 \(l\),然后二分出 \(r\) 满足 \(p_l+v_r\ge q_l+w_r\),也即 \(p_l-q_l\ge w_r-v_r\)。
\(\mathcal{O}(n\log^2 n)\)。
[ZJOI2011] 看电影 / Airplane Arrangements
I. 在平面直角坐标系中,从 \((0, 0)\) 开始,走到 \((k, n)\),一次只能向上或向右走一个单位长度,问有几种走法?
答案是 \(\binom{n + k}{n}\)。
II. 从 \((0, 0)\) 开始,走到 \((k, n)\),一次只能向上或向右走一个单位长度。定义一条路径的权值为,\(n!\times \prod \frac{1}{\texttt{向上走的连续段的长度!}}\),求所有路径的权值和。
例子:\(n=5, k = 5\),路径为 \((0,0)\to (0,2)\to (3,2)\to (3,5)\to (5,5)\),则该路径的权值为 \(5!\times \frac{1}{2!}\times \frac{1}{3!}=10\)。
答案是 \((k + 1) ^n\)。
III. 上一个问题,但是不允许经过直线 \(y=x+1\),问此时路径权值和。
答案是 \((k+1)^{n-1}\times (k+1-n)\)。
在 \(n\) 号座位后面新加一个 \(n+1\) 号座位,使得这 \(n+1\) 个座位形成一个环。
随后在这个环上执行策略,先忽略标号,共有 \((k+1)^{n-1}\) 种方案。
再考虑确定标号。由于 \(n+1\) 号座位是空的方案和原方案一一对应,因此有 \((k+1-n)\) 种方案确定座位。
[HAOI2011] Problem c / 座位安排
由于一部分人的座位已经被固定,尝试进行像上面一样的操作是不可行的。
幸好,我为了验证我转化的结论对不对,写了一个 \(\mathcal{O}(n^3)\) 的 dp。
from math import *
t = int(input())
for i in range(t):
list = input().split()
n, k = int(list[0]), int(list[1])
if n > k:
print(0, 1)
else:
f = [[0 for i in range(105)] for i in range(105)]
f[0][0] = factorial(n)
for i in range(1, k + 1):
for j in range(0, n + 1):
# for j in range(0, min(i, n) + 1):
for z in range(0, j + 1):
f[i][j] += f[i - 1][j - z] // factorial(z)
a = f[k][n]
print(a, ((k + 1) ** (n - 1)) * (k + 1 - n))
这个 dp 是可以套用到这道题上的。
模数不是质数。
残缺的字符串
想了一会儿 KMP / 后缀数据结构,发现很不可做。
考虑 shift-or 算法。复杂度为 \(\mathcal{O}(\frac{nm}{\omega})\)。
Tip: 在使用 shift-or 时,a <<= 1, a &= v
比 a = a << 1 | v
常数小 \(\frac{1}{2}\)。
Yet Another String Matching Problem
[TJOI2017] DNA
Circles of Waiting
令 \(\pi=4\)。
首先这个题是在一个(可以近似为)\(2R\times 2R\) 的正方形上做高斯消元。
但是这样复杂度是 \((4R^2)^3\),不是很能要了。
理性思考一下,设 \(f_{i, j}\) 表示从 \((i, j)\) 开始游走,走出圆外的期望步数。
有 \(f_{i, j}=p_1 f_{i-1,j}+p_2f_{i,j-1}+p_3f_{i+1,j}+p_4f_{i,j+1}+1\)。
(当 \((i,j)\) 在圆外的时候 \(f_{i, j}=0\))
运用 P10085 的套路,设出圆内 \(2R\) 个数,然后利用这些值和部分 \(f_{i, j}\) 方程推出剩下的值。
值是表示出来了,但是怎么求呢。
有一些方程由于在边界是没有用到的。我们把这些方程列出来然后进行高斯消元就行了。
\(\mathcal{O}(R^3)\)。
[省选联考 2020 B 卷] 消息传递
点分树秒了。
查的是距离刚好为 \(k\) 而不是 \(\le k\),这个可以单 \(\log\)。
[CEOI2011] Matching
字符串匹配,考虑 KMP 算法。两个字符串能匹配当且仅当它们相对大小不变。
若 \(\operatorname{equal}(S, T)=1\),则 \(S\) 与 \(T\) 的任意等长后缀与前缀也都相等。
而且这个相等具有传递性。(若没有传递性,如 P4173,则 KMP 算法很难胜任)。
如此则能使用 KMP 算法。
如何比较 \(S+a\) 和 \(T+b\) 的大小?比较 \(a\) 和 \(b\) 的排名即可。
用树状数组即可。
小清新数据结构题
考虑子树和平方的意义。
可以理解成,从子树中选一个,再选一个,求所有方案中两者点权乘积的和。
假如你改变了子树中的一个权值 \(x\to x+y\),则子树内贡献从 \(s^2\to (s+y)^2\),
\(\Delta=y(2s+y)\)
令 \(s_x\) 表示 \(x\) 的子树和,我们只需要链加、链求和即可。
不过,这些是以 \(1\) 为根的情况。对于换根操作,上面的做法是无效的。
假设根从 \(1\) 变成了 \(u\),则不在 \(1\rightsquigarrow u\) 路径上的点的贡献都不变。
在 \(1\rightsquigarrow u\) 上的点,从 \(s_u^2\) 变成了 \((N-s_u)^2=N^2-2Ns_u+s_u^2\),
这个 \(u\) 可能不太一样,但是没有啥本质区别。
还是只需要维护 \(s_u\) 就行了!
Mathematics Curriculum
什么是 “恰有 \(m\) 个不同的最大值”?
恰有 \(m\) 个下标 \(j\) 满足 \(\max(a_i,\cdots,a_j) = a_j\)。
考虑枚举最大值的位置。
之后,两边的排列就互不相关,因为跨过最大值的尝试都会被无效化。
这是一个 \(\mathcal{O}(n^5)\) 的 dp。
Mate In Three
三步必杀。
首先,先手必胜仅当 \(a<b<c\),\(2b=a+c\) 且最后一步操作了 \(c\)。
考虑怎样达成这个目标。假设后手把数放在 \(a\) 上,则有 \(x=2c-a-b\)。
后手放在 \(b\) 上也一样。(这么简单,为啥想不到呢)。
Phoenix and Earthquake
十分有意思的题目。
一个比较直观的想法是,每次拿出最大的点进行合并。
- 最大的点点值 \(\ge x\),此时可以直接合并。
- 最大点点值 \(<x\),此时如果不能合并则以后也必然不能合并。
Quantifier Question
很不传统的题。
假如 \(x_i<x_j\) 就在图 \(G\) 中连一条 \(i\rightsquigarrow j\) 的边,图 \(G'\) 中连一条 \(j\rightsquigarrow i\) 的边(都是单向边)。
第一步,判环。
然后考虑,\(i\rightsquigarrow j\) 中先确定了 \(i\),那么 \(j\) 的符号必然是 \(\exist\)。
从小到大 dfs 即可。
Future Failure
首先这道题和 \(\dfrac{n}{\prod c_i!} \bmod 2\) 有很大的关系。
\(\dfrac{n}{\prod c_i!}=\binom{n}{c_0}\binom{n-c_0}{c_1}\cdots\) 这样的组合数乘积。
又有 \(\binom{n}{m} \bmod 2=[m\subseteq n]\)
所以 \(\binom{n}{c_0}\binom{n-c_0}{c_1}\cdots\equiv 1\pmod 2\) 当且仅当 \(\forall i, c_i\subseteq n\) 且 \(\forall i\neq j, c_i\cup c_j=\varnothing\)。
但是这个有点本末倒置了。我们应该着重于求 \(\operatorname{SG}\) 函数?
令 \(\operatorname{Permu}(s)\) 表示字符串 \(s\) 本质不同的排列个数(包括 \(s\) 本身)。
-
\(n=1\),\(\operatorname{Permu}(s)=1\),Alice 必胜。
-
\(n=2\),当 \(\operatorname{Permu}(s)=1\) 时 Alice 必败,否则 Alice 必胜。
-
\(n=3\),……
当 \(\operatorname{Permu}(s)\) 为偶数的时候 Alice 必胜。
原因:能删则删,不能删就拖着。
当 \(\operatorname{Permu}(s)\) 是奇数的时候呢?
显然存在一种方法使得删掉一个字符后 \(\operatorname{Permu}(s)\) 仍然是奇数,因此当 \(n\) 为奇数的时候必胜,否则必败。
怎么 dp?容易发现这是一个子集卷积的形式,直接做 \(k\) 次子集卷积,复杂度 \(\mathcal{O}(kn\log^2 n)\)。
注意到,你每进行一次子集卷积,其实就是在一列上做一次卷积。
使用暴力实现多项式快速幂即可做到 \(\mathcal{O}(n\log^2 n\log k)\)。
Barrett:\(\lfloor\frac{a}{p}\rfloor=\lfloor a\times \frac{1}{p}\rfloor\)。
由于浮点数精度不足,用 \(\lfloor{a}\times \frac{2^{64}}{p}\rfloor/2^{64}\) 就行了。
[省选联考 2020 A 卷] 树
\(val(x)=\oplus_{u\in \operatorname{subtree(x)}} (v_u+d(u, x))\)
\(d(u, x)\) 是什么?是 \(\operatorname{dep}(u)-\operatorname{dep}(x)\)。
所以我们可以把它重写成 \(v_u + dep_u - dep_x\)。
此时这道题和 [文字内容] 没有区别,使用 DSU on tree 与值域树状数组即可。
诶呀这不是我们讨论区里的 \(\mathcal{O}(n\log^3 n)\) 做法吗?不是很妙啊。
拍到 dfn 序上就变成了区间查询。使用主席树就行了。这是 \(\mathcal{O}(n\log^2 n)\)(因为要开 \(\log n\) 棵线段树)。
……因为 [文字内容] 的影响,主席树做这个是 \(n=q=10^5,4s\) 的。
所以我决定把做法改成树状数组 + 扫描线。祝我好运。
[Ynoi2011] 成都七中
去除颜色限制
先来考虑假如只让你求联通块个数的做法。
\(u\) 与 \(v\) 联通的充分必要条件为:\(l\le \min(u\rightsquigarrow v)\le \max(u\rightsquigarrow v)\le r\)。也就是一个二维数点问题。
二维数点问题的一个经典做法是离线 + 扫描线。本题允许离线,于是我们扫描线 \(l\),用线段树维护即可。
颜色数
颜色数有一个经典解法就是 HH 的项链。但是颜色数不能合并,因此你不能直接在点分树上合并答案。
不过这个问题解决方法很简单,你只需要找到你能够到达的深度最小的祖先,然后在那里处理询问就行了。
为什么呢?
点分树性质 : \(\operatorname{LCA}(u, v)\) 必定在 \(u\rightsquigarrow v\) 的路径上。
所以如果 \(\operatorname{LCA}(u, v)\) 不可达,那么 \(v\) 也不可达。
联通有传递性,假如 \(v\) 与某个可达祖先联通,\(v\) 必定也和 \(u\) 联通。
所以,与 \(u\) 联通的点都必定在点分树上 \(v\) 这个子树内,直接在这里查询即可。
Primrose点头。我把手揣进实验袍。没有什么盛大的礼花或者道别,我知道是时候离开了。
在我走之前,我对Primrose提了最后的一个请求。
她咕哝几声,但同意了。
我摸了摸她的头。
然后消失了。