ECF23
Link
C. Equal Sums
记值域为 \(w\) 并认为 \(n,m\) 同阶,直接背包的话和的值域能够达到 \(O(nw)\),统计每个答案的复杂度也是 \(O(nw)\),于是总复杂度是 \(O(n^3w)\)。
注意到最后需要维护的信息仅仅是 \(\sum x_i = \sum y_j \Leftrightarrow \sum x_i - \sum y_j = 0\),记这个差为 \(d\),我们实际上能够通过调整两侧加入的顺序来将 \(d\) 控制在 \([-w,w]\)。
具体而言,考虑若有 \(\sum_{i=1}^a x_i - \sum_{j=1}^b y_j = 0\),可以按如下算法构造一条从 \((0,0)\) 到 \((a,b)\) 的路径:
-
设变量 \(i=0,j=0\) 表示当前位置,\(d=0\) 表示两侧和之差。
-
若 \(d \leq 0\),令 \(d \leftarrow d+x_{i+1}, i \leftarrow i+1\).
-
若 \(d > 0\),令 \(d \leftarrow d-y_{j+1}, j \leftarrow j+1\).
-
当 \(i=a, j=b\) 时停止。可以发现 \(i=a\) 时 \(i\) 不会再增加,\(j=b\) 时 \(j\) 不会再增加,故一定能够停止。
-
由此构造出三元组序列 \(P=\{i_t,j_t,d_t\}\).
可以发现一个合法的 \(P\) 一定对应唯一的 \((\{x_i\},\{y_i\})\),故其构成双射。
整个过程中 \(d\) 都被控制在 \([-w,w]\) 内,于是设 \(dp_{i,j,d}\) 表示上述算法进行到状态 \((i,j,d)\) 的方案数,用一点前缀和优化转移。时间复杂度 \(O(nmw)\).
I. Balance
考虑 \(x=\text{argmin}\{a_i\}, y=\text{argmax}\{a_i\}\),拉出 \(x \leadsto y\) 的任意一条路径 \((d_1=x,d_2,\cdots,d_k=y)\),然后:
这跟题目给出的不等号方向相反,所以所有不等号都必须取等,也就是说:
-
路径上点权递增,即 \(\forall t \in [1,k), a_{d_i} < a_{d_{t+1}}\).
-
除了路径的其他边的两个端点权值必须相等,即 \(\forall (u,v) \notin E(\text{path}), a_u=a_v\).
-
推论:任意一个点的点权必须在路径上出现过,即 \(\forall u \in V, \exist x \in V(\text{path}), a_u=a_x\).
于是将所有出现的点权排序并记 \(c_i\) 表示第 \(t\) 大点权有多少个点。枚举 \(x \leadsto y\) 的路径的 LCA,分别考虑 LCA 的前后路径。以前面的路径为例,记第 \(t\) 大点权深度最浅的点是 \(b_i\),那么必须有 \(siz_{b_i} = \sum_{j=1}^t c_j\) 且 \(b_i \in subtree_{b_{t+1}}\).
注意到对于一个点 \(u\),满足 \(siz_u = \sum_{j=1}^t c_j\) 的 \(t\) 至多只有一个,记为 \(f_u\)(若不存在则为 \(0\))。直接转移即:
DP 完枚举 LCA 统计即可,一车细节。时间复杂度 \(O(n)\).
ECF22
Link
A. Coloring
称颜色为 \(1\) 的点为黑点,为 \(0\) 的点为白点。
首先连边 \((a_i,i)\),由于每个点入度均为 \(1\),图一定是外向基环树(只关心 \(s\) 所在的连通块,可能有自环)。
先只考虑环上,容易发现任意时刻环上黑点一定形成一个区间 \([l,r]\),并且它们可以不断向右移动。枚举最后 \(l,r\) 的值以及转了几圈,就可以确定每个点变化了多少次(以及最后的颜色)。
再考虑每棵子树,环上点颜色变化的次数决定了一条链上黑白交替的最大次数。设 \(f_{u,t},g_{u,t}\) 表示黑白交替了变化 \(t\) 轮且最后是黑点/白点的最大贡献,树上 DP 即可。
枚举 \(l,r\) 可以用前缀和优化,一百车细节。时间复杂度 \(O(n^2)\).
B. Binary String
这不是我出的题吗·
不过其实环上的问题不需要转换成序列做。找到上面提到的循环移位,然后按转化后的操作容易维护某时刻所有 \(R\) 的位置(虽然这题并不需要)。
这题里扫一遍求出 \(R\) 什么时候停止移动,然后跑 KMP 算出最小周期即可。复杂度 \(O(n)\).
ECF21
Link
C. String-dle Count
所有信息可以转化为四种限制:
-
位置 \(p\) 上必须填字母 \(c\)。
-
位置 \(p\) 上不能填字母 \(c\)。
-
字母 \(c\) 出现了恰好 \(t\) 次。
-
字母 \(c\) 出现了至少 \(t\) 次。
直接子集卷积是 \(O(|\Sigma| k^2 2^k)\),无法通过。
利用一些性质,记字母 \(c\) 出现次数的下限为 \(f_c\),那么必须有 \(\sum_c f_c \leq k\),否则必然无解。
一个神奇的 trick:记 \(dp_{i,state}\) 表示填前 \(i\) 个位置,状态为 \(state\) 的方案数。\(state\) 记录每种字符 \(c\) 填了超过 \(f_c\) 个 / 未超过 \(f_c\) 个且具体填了几个。
实现时可以新建一个序列,填入 \(f_c\) 个字符 \(c\),然后直接用二进制数状压 \(state\)。总时间复杂度 \(O(|\Sigma| k 2^k)\).
UCup2nd Hangzhou
Link
C. Yet Another Shortest Path Query
平面图 Trick 题。
平面图满足性质 \(m \leq 3n-6\),由抽屉原理可得至少有一个点度数不超过 \(5\)。于是不停地删去度数 \(\leq 5\) 的点,得到每个点被删去的时间戳 \(p_u\)。
考虑将每条边 \((u,v)\) 看作两条有向边 \(u \to v\), \(v \to u\):
-
若 \(p_u > p_v\),记该边为 R 型边。每个 \(u\) 至多只有 \(5\) 条 R 型出边。
-
若 \(p_v < p_u\),记该边为 L 型边。每个 \(v\) 至多只有 \(5\) 条 L 型入边。
接下来考虑可能的路径类型,先考虑 \(len=3\),记 X 表示 L 或 R:
-
RXX
:枚举 \(s\) 的 R 型出边,转化为 \(5\) 个 \(len=2\) 的子问题。 -
XXL
:枚举 \(t\) 的 L 型入边,转化为 \(5\) 个 \(len=2\) 的子问题。 -
LRR
:按 \(s\) 离线,枚举 \(s\) 的所有 L 型出边再枚举两层 R 型出边,\(25\) 次枚举. -
LLR
:按 \(t\) 离线,枚举 \(t\) 的所有 R 型入边再枚举两层 L 型入边,\(25\) 次枚举.
LRR
与 LLR
的复杂度大约为 \(O(50m)\),同时产生了至多 \(10q\) 个 \(len=2\) 子问题。
对于 \(len=2\),同样:
-
RX
:枚举 \(s\) 的 R 型出边,转化为 \(5\) 个 \(len=1\) 的子问题。 -
XL
:枚举 \(t\) 的 L 型入边,转化为 \(5\) 个 \(len=1\) 的子问题。 -
LR
:按 \(s\) 离线,枚举 \(s\) 的所有 L 型出边再枚举一层 R 型出边,\(5\) 次枚举.
LR
的复杂度大约为 \(O(10q+m) \cdot 5 = O(50q+5m)\),同时产生了至多 \(100q\) 个 \(len=1\) 子问题。
对于 \(len=1\),直接枚举 \(s\) 的 R 型出边和 \(t\) 的 L 型入边。这里的复杂度大约为 \(O(1000q)\).
于是总复杂度上界大概是 \(O(1000q+50m)\)。注意实现时 \(len=1\) 的子问题可以直接计算,不需要存下来。
I. Dreamy Putata
列出方程,发现每一层可以由上面两层递推而来。假设不考虑 \((tx,ty)\) 处方程的特殊性,直接以前两层 \(2m\) 个点为主元,用线段树维护矩阵乘法计算转移矩阵,最后再以第一行和最后一行导出的方程组高斯消元即可。
但是 \((tx,ty)\) 处方程不一样,为 \(f_{tx,ty}=0\),所以 \(f_{tx+1,ty}\) 实际上是没有办法用前两层的主元推出的。所以设 \(f_{tx+1,ty}\) 为一个新的主元,同时由于 \(f_{tx+1,ty}\) 可以用前两层主元表示,新增了一个方程组,故最后得到的方程组数量和主元数量还是一致的。
注意上述做法有一车特殊情况,比如 \(tx=0\)(新主元和原主元会重复),\(tx=n-1\)(没有新主元,第一行少导出一个方程组)。以及由于 \(tx\) 前后转移不一样,需要分段算;以及方程里的常数项导致需要新开一个矩阵乘法线段树。
总时间复杂度 \(O(q (2m)^3 \log n)\).
ECF20
Link
K. Sticks
场上推出来结论,调了半天发现好像假了,换了个容斥做法赛后又调了一晚上。结果在写这篇题解的时候突然发现场上做法没假,改了三行过了...
设左侧第 \(i\) 行的棍子长度为 \(x_i\),上方第 \(j\) 列的棍子长度为 \(y_j\)。
定义:对于一种摆放方式,若 \(\forall i \in [1,n], y_{x_i+1} \neq i\),称其该摆放方式合法,即不存在以下形状:
...|
...|
-->∨
Lemma 1. 任意一个可能达到的矩阵 \(A\) 都存在至少一种合法摆放方式。
Proof 1. 对于 \(A\) 的任意一种摆放方式,找到最小的 \(x_i\) 使得 \(y_{x_i+1} = i\) 并令 \(y_{x_i+1} \leftarrow y_{x_i+1}-1, x_i \leftarrow x_i+1\)。调整后冲突的最小 \(x_i\) 至少增加 \(1\),故有限次调整后能找到一种合法摆放方式。
Lemma 2. 任意零一矩阵 \(A\) 至多只有一种合法摆放方式。
Proof 2. 枚举 \(k=n,n-1,\cdots,1\),不断执行以下流程:
- 求出 \(t \in [0,k]\) 满足 \(A_{k,1}=A_{k,2}=\cdots=A_{k,t}=1, A_{k,t+1}=0\). 那么必然有 \(y_k=t\),且若 \(s>t, A_{k,s}=1\) 则有 \(x_s = k\) 并删去第 \(s\) 行(若不全为 \(1\) 则终止)。
该流程要么提前终止,要么给出唯一的合法摆放方式并且没有其他可能。
Collary. 所有可能达到的矩阵 \(A\) 与合法摆放方式构成双射。
于是现在问题变为了计数满足 \(\forall i \in [1,n], y_{x_i+1} \neq i\) 的 \((\{x_i\},\{y_i\})\) 序列数量。
设 \(dp_{i,j}\) 表示考虑前 \(i\) 列且 \(\max_{t=1}^i \{y_t\}=j\)。转移考虑分成
-
若 \(y_{i+1} \leq j\),则转移为 \(dp_{i,j} \to dp_{i+1,j}\),系数直接乘上方案数即可。
-
若 \(y_{i+1} > j\),则转移为 \(dp_{i,j} \to dp_{i+1,k} (k>j)\),相当于要求 \(x_{j+1}, x_{j+2}, \cdots, x_{k-1} \leq i\) 且 \(x_k < i\),分步转移即可。
总时间复杂度 \(O(n^2)\)。
M. Bot Friends
首先注意到没有 bot 能到达 \(0\) 或 \(n+2\) 位置(容易反证),也就是说 bot 只能到达 \(n+1\) 个坑,那么必然恰有一个坑最后是空的。
同理,只考虑区间 \([l,r]\) 内的 bot,如果最后空出来的坑在最左边,称这个区间为 R 型块;如果最后空出来的坑在最右边,称这个区间为 L 型块。那么考虑整个过程,依次考虑每一步:
-
每一步中,如果移动的机器人向右并且它右边紧挨着一个 L 型块,那么它与 L 型块合并成一个新的 R 型块并重复这个过程;否则它自己成为一个新的 R 型块。
-
如果移动的机器人向左并且它左边紧挨着一个 R 型块,那么它与 R 型块合并成一个新的 L 型块并重复这个过程;否则它自己成为一个新的 L 型块。
所以整个过程始终只有未操作的 bot,L 型块与 R 型块。那么最后的局面一定是左边若干 L 型块 + 右边若干 R 型块。问题就是最小化未能合并(自己成为一个新块)的 bot 数量。
同时注意到如果在合并过程中建边,会形成一棵类似表达式树的结构,如:
-
R 型块 = '>' + (L型块)*;或者 R 型块 = '>'(花费 \(1\) 代价)
-
L 型块 = (R型块)* + '<';或者 L 型块 = '<'(花费 \(1\) 代价)
分析到这里已经可以区间 DP,记 \(f_{l,r},g_{l,r}\) 分别表示 \([l,r]\) 为 L 型块与 R 型块时的最小代价。时间复杂度 \(O(n^3)\)。
既然是表达式树,就可能可以通过从左到右扫描并维护栈来描述它。先只考虑最后全为 L 型块的情况(即最后状态的一个前缀),可以将 >
类似看作左括号并将 <
类似看作右括号,有如下规则:
-
遇到
>
:在栈上插入一个>
;如果下一个 bot 立刻将它删去,则会产生 \(1\) 的代价(对应 R 型块 = '>')。 -
遇到
<
:弹栈一次;或者花费 \(1\) 代价不删除(对应 L 型块 = '<')。
于是直接记 \(dp_{i,j,0/1}\) 表示处理到第 \(i\) 个 bot,栈内有 \(j\) 个 >
,第 \(i\) 个 bot 是否是 >
的最小代价,容易转移。
最后对左右各做一次,枚举最后状态的坑位置合并即可。时间复杂度 \(O(n^2)\)。