2024.2 记录
2.11
ARC171E. Rookhopper's Tour
todo。
2.14
NFLS 模拟. 发讲义
原题:UR #7. 水题走四方。
2.15
NFLS 模拟. 达拉然的废墟
题意:\(T\) 次询问,每次给定正整数 \(n,k\),定义一个长为 \(2n\) 的排列 \(p\) 是好的,当且仅当 \(p_2<p_4<\dots<p_{2n}\)。定义一个方案是将一个好的排列 \(p\) 划分成长度为偶数的 \(k\) 段子区间的方式。等概率随机选择一个方案,求方案中所有划分出来的子区间的逆序对个数之积的期望。
\(n,k\le 500\),\(T\le 10^4\)。
总方案数是好算的,所以考虑算所有方案的逆序对个数之积的和。这相当于是要在每段内选择一对形成逆序对的位置,问先选择一个方案,再选择这些逆序对的方案数。
一个逆序对只有三种情况:
- 两个下标为奇数的位置,由于将这两个位置交换仍然能得到一个好的排列,所以这种情况的贡献系数是 \(\frac{1}{2}\);
- 一个下标为偶数的位置和一个下标为奇数的位置,此时需要奇数位置的值小于偶数位置的值;
- 一个下标为奇数的位置和一个下标为偶数的位置,将它容斥成不限制这两个位置的大小关系,减去奇数位置的值小于偶数位置的值。
考虑按这样一个策略来确定整个排列:以某种顺序考虑所有下标,如果现在考虑了下标 \(i_1,i_2,\dots,i_k\),那么只确定 \(p_{i_1},p_{i_2},\dots,p_{i_k}\) 的相对大小关系,考虑下一个下标的时候将它的值插入到这个大小关系里。
假如已经知道了所有逆序对的位置,那么已经确定的大小关系形如一条长为 \(n\) 的有向链,链上有一些点下面挂了一个连向它的点。如果这个有向图的总大小是 \(s\),那么不在这个有向图上的位置可以任意插入,方案数是 \(\frac{(2n)!}{s!}\)。
考虑按照挂的位置从小到大确定那些挂在链下面的点的大小关系。假如有一个点挂在第 \(j\) 个偶数位置下面,且前面有 \(k\) 个挂在下面的点,那么插入它的方案数是 \(j+k\)。
于是有一个暴力:设 \(f_{i,j,k}\) 表示考虑了前 \(2i\) 个位置,划分为 \(j\) 段,且有 \(k\) 个挂在下面的点的逆序对个数之积的和。转移时,枚举下一段的右端点 \(l>i\),以及逆序对的位置 \(x,y\in (i,l]\cap \mathbb{Z}\),并分类讨论 \(x,y\) 位置取的是奇数还是偶数即可。
注意到枚举右端点和逆序对位置都是不必要的,因为可以直接顺着扫过去,额外记一维表示当前段的状态(没选,选了一个奇数位置并且钦定下一个要选奇数/偶数位置,选了一个偶数位置,选了两个)。
时间复杂度 \(O(n^3)\)。
SNOI 2019. 通信
出题人是不是不会 KM。
可以发现这个问题类似于 DAG 最小链覆盖,所以考虑把每个点拆成一个左部点和一个右部点,一开始钦定每个点都自己形成一条链,总代价是 \(nW\),对于每对 \(1\le j<i\le n\),从左部点 \(i\) 向右部点 \(j\) 连容量为 \(1\),费用为 \(|a_i-a_j|-W\) 的边,表示把 \(i\) 接在 \(j\) 后面。
这样有 \(O(n^2)\) 条边,正常费用流跑不过去(不过 KM 能过)。考虑优化建图,一种比较容易想到的方式是可持久化线段树优化建图,但还有一种常数比较小的方式:
考虑分治,假如现在要从 \((m,r]\) 中的左部点向 \([l,m]\) 中的右部点连边,将这些左部点和右部点的点权拿出来,得到 \(r-l+1\) 个虚点,然后按点权从大到小连成一条链。这样只需要从每个 \((m,r]\) 中的左部点 \(i\) 向它对应的虚点连费用为 \(a_i-W\) 的边,\([l,m]\) 中的每个右部点 \(j\) 从它对应的虚点向它连费用为 \(-a_j\) 的边,就解决了 \(a_i>a_j\) 的情况。\(a_i\le a_j\) 的情况同理。
2.16
NFLS 模拟. 零和
原题:XXII Open Cup, Grand Prix of IMO 的 K 题。
设 \(f(S)\) 是可重集 \(S\) 的零和子集个数。
如果有两个值域不是很大的集合 \(S,T\),那么可以直接将 \(T\) 内的元素整体乘上一个比较大的值,然后把 \(S,T\) 拼起来,得到一个新的集合 \(W\) 满足 \(f(W)=f(S)\cdot f(T)\)。
仿照这个思路,考虑怎么样让 \(f\) 做加法。假如限制 \(S\) 内所有元素非零,那么想拼出一个零和子集至少需要一个负数和一个正数。如果所有负数的绝对值都大于正数之和的一半,那么所有零和子集中都只有至多一个负数。这样就可以让负数之间的 \(f\) 做加法了。
具体地,随机选取一个长为 \(k=22\) 的序列 \(a_1,a_2,\dots,a_k\in [1,5]\cap \mathbb{Z}\),先做一个背包算出每个负数的 \(f\),再做一个背包算出需要加哪些负数即可。
2.17
P8860. 动态图连通性
考虑最后剩下的路径是什么样子的。设 \(t_i\) 是
2.20
NFLS 模拟. zzzyyds
2.21
POI 2012. Leveling Ground
WC 2021. 斐波那契
P5572. 简单的数论题
P5605. 小 A 与两位神仙
2.22
NFLS 模拟. travel
2.23
NFLS 模拟. 形式化题面
2.24
WC 2024. 线段树
确实可以直接 DP。不过我在考场上认为可以把每个区间直接拆成若干线段树区间,属实错得离谱。
先考虑如果只有一个询问区间,应该怎么做。从下向上 DP,每个线段树节点有三种状态:
- \(-1\):可以从它的子树内知道它的和;
- \(0\):不能从它的子树内知道它的和,但我们不关心它的和;
- \(1\):不能从它的子树内知道它的和,且我们关心它的和。
假如当前要算 \(u\) 的 DP 值 \(f_{u,-1/0/1}\),设 \(u\) 的左右儿子是 \(v_1,v_2\),感性理解一下,不合法的转移几乎只有 \(f_{v_1,0}\times f_{v_2,1}\to f_{u,*}\),因为不能根据 \(u\) 的和,在不知道 \(v_1\) 的和的情况下还原 \(v_2\) 的和。
推广到有多个询问区间的情况,此时每个线段树节点的状态有:
- \(-1\):可以从它的子树内知道它的和;
- \(S\):需要知道在 \(S\) 内的询问的和。
因为每个询问的状态是独立的,所以转移和只有一个询问区间的情况相同。
发现在这个状态中,对于每个 \(u\),只有 \(O(N)\) 个 \(S\) 使得 \(f_{u,S}\) 有值。这是因为每个有值的 \(S\) 一定是从 \(u\) 到 \(u\) 子树内某个点的路径上的询问的并。
把 \(-1\) 这个状态分离出来设为 \(g_u\),发现对于剩下的 \(f_{u,S}\),只有在 \(S_1=S_2\) 的情况下才会有转移 \(f_{v_1,S_1}\times f_{v_2,S_2}\to *\)。设 \(S_1\) 是 \(v_1\leadsto x_1\) 路径上询问的并,\(S_2\) 是 \(v_2\leadsto x_2\) 路径上询问的并,设 \(T\) 是根到 \(u\) 路径上询问的并,由于 \(T\cap S_1=T\cap S_2=\varnothing\),所以可以直接把状态中的 \(S_1,S_2\) 并上 \(T\)。此时,\(x_1\) 和 \(x_2\) 能够转移,当且仅当包含 \(x_1\) 和包含 \(x_2\) 的询问区间集合完全相同。
给每个询问区间随机一个权值,对每个点统计包含它的询问区间的权值异或和,然后 DP 的合并就只需要把权值相等的位置合并,可以用线段树合并或 std::map
启发式合并维护。时间复杂度 \(O(N\log N)\) 或 \(O(N\log^2 N)\)。
2.26
USACO 2024 Jan Platinum. Island Vacation
我的题解。
2.28
统一省选 2021. 图函数
秒了。
考虑 \(f(u,G)\) 的计算过程,如果一个 \(v\) 真的被删去了,那么说明 \(u\leadsto v\leadsto u\) 这条路径上的点都满足被删去的条件。所以在考虑 \(v\) 是否被删去的时候,可以直接删去编号 \(<v\) 的所有点。
于是 \(h(G)\) 就是下面这个东西之和:
- 对于每个 \(1\le u\le n\),在只保留编号 \(\ge u\) 的点时,\(u\) 所在的强连通分量的大小。
我们发现 Floyd 的过程完美符合“只保留编号 \(\ge u\) 的点”这个条件。于是设 \(f_{u,i,j}\) 表示 \(i\leadsto j\) 的路径,除了两个端点外的点的编号都 \(\ge u\) 的情况下,路径上边权的最小值最大是多少。(认为输入的第 \(i\) 条边具有边权 \(i\)。)
答案是容易统计的,且 \(f\) 数组的第一维可以去掉。时间复杂度 \(O(n^3+m)\),循环展开后可以通过。
2.29
统一省选 2023. 城市建造
除了重心以外的部分都想到了。
考虑两个关键点 \(u,v\),对于任意一条 \(u\) 到 \(v\) 的简单路径,其中所有点都需要是关键点。所以对于每个点双连通分量,只要其中有关键点,那么其中所有点都是关键点。
于是建出圆方树,我们可以认为,把某个点双中的点都设置成关键点,等价于把这个点双对应的方点删去。此外,还需要满足如下条件:
- 如果认为中间只有一个圆点的两个方点是相邻的,那么所有被删去的方点形成一个连通块;
- 删完方点后的圆方树上,任意两个连通块的圆点个数相差不超过 \(k\)。
当 \(k=0\) 时,直接枚举连通块大小 \(i\mid n\),在圆方树上钦定任意一个圆点为根,对于每个圆点 \(u\),如果 \(i\mid \mathrm{size}_u\),那么需要把 \(u\) 的父亲删去。然后 DFS 一遍整棵树,检查这样一种删除方案是否合法即可。
当 \(k=1\) 时,有一个性质是,假如将圆方树以带权(圆点权为 \(1\),方点权为 \(0\))重心 \(r\) 为根,那么所有被删去的方点需要是一个在根处的连通块。
于是设 \(f_{u,i}\) 表示:
- 如果 \(u\) 是圆点,假如 \(u\) 的父亲已经被删除,\(u\) 的子树内有多少种方案,使得每个连通块的大小都在 \(\{i,i+1\}\);
- 如果 \(u\) 是方点,定义 \(f_{u,i}=\prod_{v\in \mathrm{son}_u} f_{v,i}\)。
看起来转移时需要做背包,但其实不用。固定 \(i\),对于每个 \(u\) 的儿子 \(v\),如果 \(\mathrm{size}_v<i\),那么 \(v\) 一定不能被删去。而如果 \(\mathrm{size}_v=i\),至多保留一个这样的 \(v\)。
最后,分析一下可能满足条件的 \(i\) 的个数。注意到需要有 \(\frac{\mathrm{size}_u}{i}\ge \mathrm{size}_u\bmod i\),推一下得到 \(\lfloor\frac{\mathrm{size}_u}{i}\rfloor\ge \lceil \frac{\mathrm{size}_u}{i+1}\rceil\),这样的 \(i\) 一定在整除分块的边界处,于是只有 \(O(\sqrt{n})\) 个。
对 \(k=0\),时间复杂度为 \(O(n\sigma_0(n)+m)\);对 \(k=1\),时间复杂度为 \(O(n\sqrt{n}+m)\)。