4 月做题记录
P11920
将一个数字数位任意排列,其 \(f\) 值不变。
注意到有很多 \(f(x)=0\),考虑先求出 \(1\) 到 \(9\) 的答案,\(0\) 的答案即可算出。
枚举所有 \(f(x) \neq 0\) 且 \(x\) 数位单调不降的 \(x\),每个 \(1 \leq y \leq n\) 且 \(f(y) \neq 0\) 的 \(y\) 唯一对应一个这样的 \(x\)。
打表发现 \(x\) 的数量大概是 \(6 \times 10^4\) 量级,对每个 \(x\),枚举 \(y\) 与 \(n\) 的 LCP 即可,其中 \(y\) 是 \(x\) 数位随意排列得到的某个结果。
P12003
由于 \(10^8\) 内 \(\max \omega(x) \leq 8\),质因数分解后直接跑树上莫队就行。质因数分解的时候需要先处理一下 \(\sqrt V\) 以内的质数。这样分解的复杂度是 \(O(\dfrac{n\sqrt V}{\ln V})\) 的。
P11918
显然取的 \(p\) 是大到小排序后的一段前缀。
平方 DP 是,\(f_{i,j}\) 表示前 \(i\) 题,获得 \(j\) 分的概率。
将状态中 \(f_{i,j} \leq \varepsilon\) 的状态忽略,可以证明状态数是可接受量级,取 \(\varepsilon = 10^{-14}\) 可以通过。
P7215
对于每个连通块,在点分树中深度最小的点处统计答案。
也就是说,考虑点分治,对于每个分治重心,求出包含这个点且在目前子树内部的最小连通块。
这个过程一次 DFS 即可。
P5576
先把串拼在一起建立 SAM,对于每个串 \(s_i\) 找到其所有前缀在 SAM 上的位置,把这些点染色为 \(i\)。
询问变成找到一个权值最大的点使得其子树内存在 \([l,r]\) 中每种染色。
按照 \(r\) 扫描线,树剖后变为区间覆盖颜色,查询颜色 \(\leq x\) 的点的权值最大值。ODT 并维护线段树即可。
QOJ5523
直接状压 DP 是,\(f_{x,y,S}\) 表示从 \(x\) 出发,结尾为 \(y\),经过了 \(S\) 这个集合是否可行,复杂度 \(O(n^32^n)\)。
考虑将 \(x\) 到 \(y\) 的哈密顿路径从 \(1\) 号点分割开,记 \(f_{x,S}\) 表示从 \(1\) 出发经过 \(S\) 这个集合,最终到达 \(x\) 是否可行。则询问 \((i,j)\) 时枚举全集的包含 \(1\) 的两个子集划分即可。复杂度 \(O(n^22^n)\)。
注意到 \(f_{x,S}\) 表示一个 \(0/1\) 结果太慢了,直接记 \(f_S\) 为一个 \(2^n\) 的数,二进制第 \(x\) 位表示 \(f_{x,S}\) 即可。复杂度 \(O(n2^n)\)。
AGC031E
枚举偷了 \(k\) 颗宝石。
如果只有 \(x\) 一维的限制,考虑将所有偷了的宝石按 \(x\) 排序,限制变为了对每颗宝石确定了一个区间。
对于 \(x,y\) 两维,做法类似,考虑用费用流刻画限制,每个宝石拆成入点和出点表示只能选一次,左侧右侧各 \(k\) 个点表示按照 \(x\) 或 \(y\) 排序后每一个选了谁,对符合条件的宝石连边即可跑最大费用最大流,范围很小可以通过。
QOJ5419
注意到对于一个锐角三角形,取三边中点连线可以将之前的一个变成新的四个。
于是若 \(k\) 有解,则 \(k+3\) 也有解。
可以证明 \(k < 8\) 时无解,只需要构造 \(k=8,9,10\) 的答案,这个需要手玩若干组。
QOJ4812
有一个 \(O(n^2)\) DP 是,\(f_{i,j}\) 表示和为 \(i\),最后一个数为 \(j\) 的答案。
注意到若 \(a_1 \leq O(\sqrt n)\),则 \(j \leq O(\sqrt n)\),这部分复杂度是 \(O(n\sqrt n)\) 的。
考虑 \(a_1 > O(\sqrt n)\),此时我们可以得到序列长度是 \(O(\sqrt n)\) 级别的,所以序列极差不超过 \(O(\sqrt n)\)。
考虑从后往前 DP,记 \(f_{i,j}\) 表示目前序列长度为 \(i\),且 \(\sum \limits_{k > 1} a_k - a_1 = j\) 的答案,每次将 \(a_1 - 1\) 或 \(a_1 + 1\) 加入序列前部,则 \(j\) 的变化即为 \(i\) 或 \(-i\)。
分析复杂度,\(i\) 的状态数是 \(O(\sqrt n)\) 的,\(j\) 的状态数是 \(O(\sqrt n \times \sqrt n) = O(n)\) 的,总复杂度 \(O(n \sqrt n)\)。
QOJ5034
考虑将一条路径视作一个字符串,那么字符集大小为 \(n\),限制变成了 \(1\) 到 \(n\) 的字符串不能包含任何一个给定的字符串。
这个条件显然提示我们建出 AC 自动机。特别地,字符集大小是 \(n\),所以建立 AC 自动机时需要维护可持久化线段树,具体地对于每个点 \(u\),考虑其 Trie 图的出边大部分都和 \(fail_u\) 的出边相同,只有儿子对应的出边不同。于是可以用可持久化线段树维护。
将 \(1\) 到 \(n\) 这 \(n\) 个点作为长度为 \(1\) 的字符串也加入 AC 自动机,那么每个状态对应的原图中的点就是这个状态对应字符串的末尾字符。直接在图上跑最短路,但边数是 \(O(n^2)\),无法通过。
考虑刚才建立 AC 自动机的过程,发现对于点 \(x\),其很多出边都和 \(fail_x\) 出边相同,于是每次从状态 \(x\) 出发松弛时,DFS 对应的可持久化线段树,无法松弛时将这个点标记为无效,一个子树无效时将子树删去。这样可以简单势能分析出边数为线性量级。
CF1750G
枚举 \(p’\) 和 \(p\) 的 LCP 长度为 \(i-1\),要求 \(p'_{i} < p_i\)。
直接刻画 \(f(p')\) 是难的,考虑容斥变成钦定。
即我们需要对于每个 \(k\) 计算 \(p'[i,n]\) 选择 \(k\) 个 \(+1\) 段的方案数。这个列出式子后可以范德蒙德卷积做到 \(O(1)\)。对于每个 \(i\) 容斥即可做到 \(O(n^3)\)。
复杂度瓶颈在于容斥,考虑将所有 \(k\) 的答案一起做容斥。记 \(f_{i,j}\) 表示考虑 \(p'[i,n]\) 选择 \(j\) 段的方案数,对于每个 \(i\) 决策是否将 \(i\) 作为结尾分一段即可。复杂度 \(O(n^2)\)。
QOJ6816
枚举长串 \(s_k\),则可以发现 \(s_i\) 必然是 \(s_k\) 的某个前缀的最长或次长关键后缀,其中关键指的是这个串是输入的某个串。
考虑把所有这样的串拉出来,考虑什么时候其作为 \(s_i\) 是可行的,则考虑其所有作为关键位置出现过的,在 \(s_k\) 中构成若干个区间。考虑所有包含这个区间的关键区间,则这些区间对应的字符串至多只有 \(1\) 个。这个可以简单扫描线。
还不够,\(s_i\) 还可能作为某个前缀的至少第 \(3\) 长后缀,这也是不合法的,但是由于我们并没有添加这样的区间,可能导致答案算的不对,所以将每个前缀的次长后缀在 AC 自动机的 Fail 树上到根路径标记为不合法即可。
QOJ4912
考虑维护一个指针 \(p\) 指向内存的第 \(p\) 个 bit。每次调用,若第 \(p\) 个 bit 为 \(1\),将 \(p\) 这个 bit 设为 \(0\),然后 \(p \gets p + 1\),否则将 \(p\) 这个 bit 设为 \(1\),然后 \(p \gets 0\)。则第一次到达 \(p = i\) 的时间即为 \(2^i\)。
维护 \(p\) 只需要 \(\log \log 26\) 个 bit,所以每次至多操作 \(6\) 个 bit。
QOJ8044
对输入的 \(t\) 分块维护哈希值,维护所有整块的哈希和最后散块的哈希。
对于输入到 \(s_i\),考虑判定 \(s[i-len_t + 1,i] = t\) 是否成立,对于最后散块的那个维护哈希,对于每个 \(i \bmod B\) 和之前的整块结果做 KMP 即可。
竞赛图最小割
考虑 \(s,t\) 最小割是选择一个集合 \(s \in S\) 和 \(t \notin S\)。
现在考虑将本不属于 \(S\) 的点 \(u\) 加入 \(S\),可以发现割的权值加上 \(out_u - |S|\),\(out_u\) 为点 \(u\) 出度。
所以选择的点 \(u\) 是 \(out\) 排序后的一段前缀,可以容易计算。
QOJ5305
先将 \(1\) 放到 \(a_1\),依次加入 \(2,3,4,\cdots,n\),可以简单的把 \([1,i]\) 前缀放到后面再转回来,最后若干个可能不行需要爆搜一下。
ARC138F
对于合法序列计数问题,常见的做法是考虑什么样的序列合法,另一种是对操作序列计数。操作序列唯一对应结果序列是简单的,否则处理方式是容斥或者钦定对每个合法序列的代表元计数。
这个题不容易进行判定,考虑对于每种点列确定一个代表操作顺序,例如字典序最小的操作顺序,于是可以进行类似二维区间 DP 状物。
记 \(f_{i,j,k,l}\) 表示 \(x \in [i,j]\),\(y \in [k,l]\) 的点构成的集合的答案。
考虑将字典序最小刻画得更具体,我们优先操作编号较小的位置,编号相同时优先操作 \(x\)。枚举第一次操作的位置,可以进行容斥。复杂度 \(O(n^6)\)。
CF2086E
注意到一个数的权值算法应该是,每次贪心取最大的能减去的数然后减去。进一步发现 \(k\) 不会很大,大概不超过 \(200\) 的样子。
记 \(a\) 表示所有给定的有效数,直接记忆化搜索,记 \(f_{i,j,x}\) 表示要计算有多少 \(\leq i\) 的数,从 \(a_j\) 开始减,最小次数为 \(x\)。转移只需要枚举 \(y\) 能减去多少次 \(a_i\) 并得到新的范围即可。
复杂度比较显然的是对的。
QOJ7677
直径中点唯一,记 \(f_{i,j,k,x}\) 表示直径中点为 \(i\),半径为 \(j\),上一次从 \(k\) 来,删除序列末尾 \(x\) 个数可以插空的方案数,转移考虑枚举新的直径中点往哪个方向移动。
P10145
考虑部分分:需要保证所有区间的值都能被求出。
考虑若知道 \([l,r]\) 的区间和,相当于连边 \(l\) 和 \(r+1\),在这个题中相当于对于每个区间 \([l,r]\),连边 \(l\) 与 \(r\),要求整个图连通。
考虑把线段树的结构画出来,对于一个区间 \([l,r]\) 的子树进行考虑,可以发现所有的边形如一个三角嵌套的形态。我们发现对于区间 \([l,r]\) 和中点 \(mid\),若 \(mid\) 同时不与 \(l,r\) 连通,则 \(mid\) 之后一定无法和外面的连通,所以这样是不合法的。可以这样记状态:\(f_{i}\) 和 \(g_i\) 分别表示点 \(i\) 子树合法的情况下,\(l_i\) 与 \(r_i\) 是否连通的方案数。有转移 \(f_i = 2 \times f_{ls} \times f_{rs} + f_{ls}g_{rs} + f_{rs}g_{ls}\),\(g_i = f_{ls}g_{rs}+g_{ls}f_{rs}\)。
考虑原题,进一步刻画子树的形态,发现对于区间 \([l,r]\) 构成的子树,若 \(l\) 和 \(r\) 不连通则必然存在一个分界点 \(i\) 使得所有与 \(l\) 连通的点 \(\leq i\),与 \(r\) 连通的点 \(>i\)。不妨认为 \(i\) 是最大的与 \(l\) 连通的点。
然后考虑扩展这个 DP 状态,\(f_{i,j}\) 表示 \(i\) 子树分界点为 \(j\) 的答案,\(j=0\) 时认为 \(l_i,r_i\) 连通。转移写出来后可以线段树合并维护,复杂度 \(O(n \log n)\)。
LOJ576
可以发现选的区间是前缀或后缀,可得答案等于 \(\sum \limits_{i=1}^n \min(\gcd \limits_{j=1}^{i} a_j, \gcd \limits_{j=i+1}^n a_j)\)。
显然求出所有本质不同前缀和后缀 \(\gcd\) 即可,因为前缀 \(\gcd\) 和后缀 \(\gcd\) 的变化次数为 \(O(\log V)\) 量级,在线段树上二分出所有变化点即可。复杂度 \(O(n \log n \log V)\)。
LOJ3885
这个东西看着就很可以调整法。
没有 MST 的限制时,是一个经典问题,将区间按照右端点排序每次取区间内大于等于 \(l\) 的最小权值即可。
有 MST 的限制时,相当于对于每条非树边,要求树上这条路径边权都小于这条边的边权。
对于树上的一条边区间 \([l,r]\) 和这条非树边区间 \([l',r']\),则可以发现可以进行 \(r \gets \min(r',r)\) 与 \(l' \gets \max(l',l)\)。
我们声称原问题有解等价于对于每条非树边和树上这条路径上的边这样操作后有解。必要性显然,考虑充分性。对于这样的区间构造答案后,对于每条非树边,考虑求出树上这条路径的最大的边权,若这条非树边比这条树边权值大,就交换这两条边的权值。
可能需要树剖维护一下,复杂度 \(O(n \log^2 n)\),当然精细一点可以做到 \(O(n \log n)\)。
P10433
考虑确定 \(1\) 号人目标点 \(u\) 时,其余人会怎么走。这个东西和每个人行动的轮数有关。
因为我们需要 \(1\) 号到达 \(u\),所以其余点经过轮数相同,假设为 \(x\)。
我们考虑每个人怎么走,可以看出来有两种行动方式:从起点到达某个终止点后,每轮走 \(2\) 步。或者从起点到达某个终止节点且这个点有相邻的终止节点,然后每轮只走 \(1\) 步。对于固定的 \(x\),可以看出这个东西是前面一段斜率为 \(2\) 的直线,后面跟着一段斜率为 \(1\) 的直线。并且对于每个点这条直线拐点都容易计算,进行一个多起点 BFS 即可。
于是我们得到了一个 \(O(n^2)\) 做法,记 \(f_{u,x}\) 表示从 \(1\) 号的起始点到 \(u\),经过 \(x\) 轮花费的最小步数,则 \(u\) 的答案为 \(\min \limits_{x} \{f_{u,x}+g_x\}\),\(g_x\) 是其他点出发走 \(x\) 轮的最小值。
注意到 \(g_x\) 是若干个两段的分段函数相加,所以 \(g_x\) 必然是上凸的!对于每个 \(u\),考虑怎么样的 \(x,f_{u,x}\) 是有用的,发现 \((x,f_{u,x})\) 构成的下凸壳上的点才有用,下凸壳上的点数量为 \(O(n^{\frac{2}{3}})\),所以直接跑最短路并只保留下凸壳的点就是 \(O(n^{\frac{5}{3}})\) 的复杂度。
LOJ3077
神题!
我们先希望得到一个多项式复杂度算法。
我们考虑聪明的爆搜,对于一个环,我们希望这个环在每个点作为起点时恰好被搜到两次,也就是两个方向各一次。这样每个长度为 \(x\) 的环,其会被搜到 \(2x\) 次,搜索过程中比这个数大则直接判定为有解。
现在我们希望对于每个点作为起点搜出所有包含这个点的环,并且只访问环上的边。这个是容易做到的,对于目前 DFS 到的一个点 \(u\),进行一次连通性的 DFS 判定能否不经过目前在搜索栈内的点回到起点,这样只会访问环上的边,我们得到了一个 \(O(n^4)\) 的做法。
进一步,发现 \(m>2n\) 时必然存在解,因为每条非树边至少贡献一个简单环。
事实上 \(m > n+2\sqrt n\) 时也有解,具体证明比较复杂,大概是你考虑删掉 \(O(\sqrt n)\) 条边时图中期望还有多少个环。
考虑 \(m \leq n + 2\sqrt n\),此时你考虑图上有大量的二度点,你把二度点缩起来可以得到一张带权图,点数是 \(O(\sqrt n)\) 级别。在这个图上跑搜索即可得到 \(O(n^2)\) 的复杂度。
山东省集 D5T2
考虑每次操作都是全局怎么做。
记 \(p_i\) 表示有多少 \(1 \leq j < i\) 且 \(a_j >a_i\),考虑一次冒泡排序的本质是,将所有 \(p_i = 0\) 的 \(i\) 移动到下一个 \(p_j = 0\) 的 \(j\) 之前,对于 $p_i >0 $ 的 \(i\),将 \(i\) 往前移动一步后 \(p_i \gets p_i - 1\)。
将所有往前移动一步的操作视为整体操作,容易用堆维护操作并最终还原序列。
现在考虑原题。看着就不可能做到 polylog,考虑根号状物。
有一个比较好写的做法是时间轴分块,也就是定期重构。考虑在时间轴上的每一块,将这块涉及到的操作的左右端点视为关键点并分块,这样操作只有整块操作。发现块之间比较独立,每一块类似全局操作维护一个堆,但是可能存在一个块的末尾和下一块的开头交换,这个应该是比较容易处理的,更新一下逆序对数和堆即可。
这样复杂度是 \(O(n \sqrt n \log n)\) 的。
山东省集 D4T2
有一个很直接的序列分块做法:每一块维护 01 Trie,整块打标记并在树上下传,散块暴力重构,查询时把散块的数也建出 Trie,然后考虑多棵树同时二分。设块长为 \(B\),修改操作复杂度 \(O(B \log V+\dfrac{n}{B})\),查询复杂度 \(O((B+\dfrac{n}{B})\log V)\),只能取 \(B = \sqrt n\) 做到 \(O(n \sqrt n \log V)\),不够优秀。
我们希望把 \(\log\) 放进根号里,查询的二分看着就去不掉,所以 \(O(\dfrac{n}{B} \log V)\) 没法优化,于是我们希望把 \(O(B \log V)\) 的部分优化掉。
\(O(B \log V)\) 的两个瓶颈在于,修改时对散块重构,以及查询时对散块单独建树。
类似后缀树,注意到 \(n\) 个数构成的 01 Trie 只有 \(O(n)\) 个度数至少为 \(3\) 的点,也就是说如果我们只维护给定数的叶子建出的虚树就可以得到更优的复杂度,这个做法叫做维护压缩 Trie。
具体地,我们先考虑,给定若干个数,线性复杂度内建出压缩 Trie,这有一个前提是这些数已经排好序。这个时候求两个数的 LCP 即为他们的 LCA,按照单调栈建虚树的方式建立即可。
于是我们对于每个块只维护压缩 Trie,现在我们还需要求出每个块排序后的结果,这是很容易的,整块打标记,散块把修改的部分在 Trie 上 DFS 可以得到新的顺序,和未修改部分归并。查询时把左右散块进行归并即可。复杂度 \(O(n \sqrt {n \log V})\)。
ARC144E
先删去无用的点,即不能从 \(1\) 到达或不能到达 \(n\) 的点,这些点显然不影响答案。
将点权变成边权,这是很容易通过拆点实现的。
考虑这样的一个数 \(x\) 什么时候符合条件。容易发现对于任意一个点 \(i\),\(1\) 到 \(i\) 路径点权和模 \(x\) 意义下应该有唯一值,记为 \(d_i\),则限制变为对于每条边 \((u,v,w)\),要求 \(d_v \equiv d_u + w \pmod x\)。并且边权未定的边是不重要的,只需要存在这样的 \(d\) 使得条件成立,那么对于每条未定边都可以指定一个 \(w\)。
将有向边看成无向边后直接带权并查集维护,对于每条非树边要求的是 \(x\) 为一个数的约数,对所有限制取 \(\gcd\) 即可。
LOJ3835
考虑一个出度为 \(0\) 的点显然无意义,因为到达了这个点后入边被反转但是不能往回走,又无其他出边,所以我们构造的路径必然不包含这样的点。
另一方面考虑若起点出度为 \(1\),则第一步和最后一步唯一确定,可以变成起点为其唯一出点的情况。
现在考虑起点度数至少为 \(2\),且不存在出度为 \(0\) 的点。此时每个点出发都能走进某个环。
随便找起点的两个不同出点,考虑通过这两个点出发进行一个构造。若存在两个点不交的环可以分别被这两个点到达,则走两次这样的环即可。否则考虑应该有一个环使得这两个点能同时到达,找到这个环上两个点出发到达的第一个点,从两边走两次即可将环上边反转的同时回到起点。
ABC400F
记 \(f_{l,r}\) 表示区间 \([l,r]\) 目前颜色可都视作为 \(0\) 时到达目标结果的最小花费,\(g_{l,r}\) 表示区间 \([l,r]\) 中左端点已经被染成 \(c_l\) 但是染色区间未定的最小花费。则 \(f_{l,r} = x_{c_l} + g_{l,r} + 1\),考虑 \(g_{l,r}\) 的转移,枚举一个 \(c_x=c_l\) 表示这次染到了 \(x\),则花费为 \(g_{x,r}+x-l+f_{l+1,x-1}\),对所有权值取最小值即可。
ABC400G
可以猜测到关于 \(k\) 的答案是凸性的。
考虑经典的分治 DP,记 \(f_{l,r,x,k}\) 表示区间 \([l,r]\) 内选了 \(k\) 个数,三个类别选的数的奇偶性状压为 \(x\) 时的答案。转移形如常数次从左侧和右侧的区间进行 \((\max,+)\) 卷积。由于凸性直接闵可夫斯基和做差分归并即可。
CF2084F
记 \(ra_i\) 表示 \(i\) 在 \(a\) 中出现位置,\(rb_i\) 同理。
考虑一个排列 \(b\) 是好的,当且仅当对于任意 \(ra_i < ra_j\) 有 \(rb_i < rb_j\)。必要和充分性都容易证明。
则对于每个 \(c_i = 0\),只考虑 \(c_i>0\) 的数的贡献,容易求出 \(b_i\) 的一个范围,对这些范围按照 \(r\) 排序后贪心填即可。
观察一下区间的形态可以发现,填入的 \(b\) 之间必然不会导致不合法,所以直接这么做就是对的。
CCPC 2020 秦皇岛
B. Bounding Wall
发现 \(O(nm \log nm)\) 的复杂度是足以通过的。
对于每个点维护出其四个方向第一个不符合条件的点,查询枚举矩形另一条边上的在这个十字上的点,线段树二分即可。
D. Defend City
可以证明要么左上右下选的点数均为 \(1\),要么左下右上选的点数均为 \(1\)。两部分是对称的,考虑左上右下都只选了 \(1\) 个点。
枚举左下的点中最靠上的那个,发现每次选的下一个点都可以通过贪心唯一确定。进一步地,处理出每个矩阵后继后倍增即可做到 \(O(n \log n)\)。
H. Holy Sequence
考虑刻画一下一个数的出现次数的平方。
常见做法是两种:考虑组合意义 \(x^2\) 等于 \(x\) 个数中有序选两个,然后拆成一对数的贡献,这个题中这么做应该也行但我没细想。
另一种是考虑代数意义,在 DP 时记录 \(\sum x^0,\sum x, \sum x^2\),转移时考虑二项式展开即可。
多项式做法的朴素 DP 还是很容易的,但是次数很大。我们考虑整个序列的形态到底是怎么样的,序列是由若干个连续段连在一起,第 \(i\) 段的开头数为 \(i\),其余数不超过 \(i\)。这启发我们枚举 \(t\) 在序列中第一次出现的位置,也就是 \(t\) 这一段的开头位置在哪里。可以发现这个位置之前的数必然不会为 \(t\),这之后有若干段,除了段开头外其他都可以作为 \(t\)。这个位置前面的方案数容易 DP,后面的记一个 \(f_{i,j,0/1,0/1/2}\) 表示到了 \(i\),目前所有数要求不超过 \(j\),\(i\) 是否为一段的开头,后面的表示记录的是 \(\sum x^0\) 或 \(\sum x^1\) 或 \(\sum x^2\)。转移很容易。复杂度 \(O(n^2)\)。
J. Jewel Splitting
枚举 \(d\) 计算所有区间的复杂度是调和级数的,枚举 \(n \bmod d\) 的段起点在哪后可以动态维护每个哈希值出现次数。
K. Kingdom's Power
钦定哪些叶子作为士兵终点后,非虚树上的边被计入 \(2\) 次贡献,此外还要加上选的点的深度和。
直接 DP,记 \(f_{i,0/1}\) 表示 \(i\) 子树内是否存在被选叶子时的最小答案即可。
L. Lost Temple
好题!
首先注意到相邻两列答案差的绝对值不超过 \(1\),这是因为一列消失后下一时刻相邻的列必然也会消失。
暴力枚举每列的答案,现在问题转为判定某列答案是否大于等于 \(x\)。
考虑第 \(i\) 列答案是否不小于 \(x\),把整个过程的图动态画出来可以发现,要求存在第 \(i\) 列上的某个位置,使得以其为中心的半径为 \(x\) 的斜 \(45\) 度正方形内所有点都在给定的图形内。考虑这个东西的本质是,有一个区间 \([l,r]\),然后对于 \(0 \leq y < x\),区间 \([l,r] \subseteq [l_{i-y},r_{i-y}]\) 且 \([l,r] \subseteq [l_{i+y},r_{i+y}]\)。这个可以变成区间 RMQ 问题。
如果使用线性 RMQ 已经可以得到 \(O(n)\) 的做法了,但是我们考虑更简单的做法。
注意到相邻两列答案不超过 \(1\) 其实还有用,你把询问的区间画出来发现大致是呈现左右端点均单调不降的情况,虽然可能存在一个端点往前移动 \(1\) 的问题,这个时候你只需要对多出来的部分直接计算答案而不是移动指针。这样单调队列即可,复杂度 \(O(n)\)。
CCPC 2020 威海
B. Labyrinth
给定起点终点为对角线的矩形内如果没有黑洞,答案是两点曼哈顿距离。
否则可以发现,必然存在一条最优路径,经过某个黑洞的四周相邻点。
把黑洞相邻点拉出来对所有点跑最短路,讯问时枚举从哪个关键点经过。复杂度 \(O(nmk)\)。
C. Rencontre
显然的,三个点 \(u,v,w\) 的对应答案为 \(\dfrac{1}{2}(dis(u,v)+dis(u,w)+dis(v,w))\)。
根据期望线性性,只需要求 \(dis(u,v)\) 期望,其他类似。
这个东西直接枚举 LCA 就能计算了,复杂度线性。
E. So Many Possibilities...
好题啊!
我们考虑一个操作序列的概率是多少,应该是每个前缀中目前还存活的怪的倒数相乘。
我们现在考虑对于一个操作序列,我们确定一些位置使得这个位置的操作结束后这只怪被打死了。发现如果我们确定了这些位置,那么每个前缀中存活的怪数量是可以唯一确定的。
具体地,我们考虑一个 DP 状态 \(f_{i,S}\),表示进行了 \(i\) 次操作,\(S\) 这个集合内的怪现在被打死了,且将不对 \(S\) 内怪物的攻击视为对同一只怪攻击时的总概率。这个 DP 可以通过枚举下一次打的怪是否会死亡进行转移,复杂度 \(O(nm2^n)\)。
接着考虑对于每个状态 \(m,S\),讲那些不对 \(S\) 内的攻击确定方案数,直接背包即可。不能直接对每个 \(S\) 单独进行一次背包,直接从 \(S\) 去掉其最低位后的 DP 结果进行更新即可,复杂度 \(O(m^22^n)\),可以通过。
F. Skeleton Dynamization
这个题很牛啊!
首先我们考虑这个分层的图结构,可以发现整个图中度数最小的点必然是在最上或最下的一层里。于是考虑 \(u\) 为图中任意一个度数最小的点,设其为分层的图中最上面的一层。
考虑枚举其下一层对应的点 \(v\),满足 \((u,v)\) 存在边。现在我们尝试还原前两层,因为只要前两层点确定后面的层可以唯一推出。
考虑对于每个点 \(i\) 求出到 \(u\) 的最短路和到 \(v\) 的最短路,考察连接第一二层的两个点 \((x,y)\) 的点符合什么条件,可以发现必然是 \(x\) 到 \(u,v\) 最短路较短的和 \(y\) 到 \(u,v\) 最短路较短的值相同,显然可以将第一层的所有点求出,对于每个点枚举其出边对应的第二层的点即可。这样整个分层图就被唯一确定。
考虑复杂度,容易发现 \(deg_u \leq O(\sqrt m)\),所以总复杂度 \(O(m \sqrt m)\)。
K. Tree Tweaking
考虑将深度之和改为子树大小之和。
考虑将 \(p_l\) 到 \(p_r\) 随意排列的本质是什么。
将每个点 \((p_i,i)\) 构成的二叉搜索树画在平面上,本质上是一棵笛卡尔树状物。发现 \([1,l-1]\) 的点的子树大小,和 \([r+1,n]\) 的子树大小,都是与 \([l,r]\) 内的排列是无关的。
于是只需要最小化 \([l,r]\) 中的点排列后的子树大小和的最小值。
考虑把这些点按照连通性拆成若干连通块,显然每个连通块之间无论如何排列都不影响,对于每个连通块内的单独考虑。区间 DP,记 \(f_{l,r}\) 表示将这一段内的点建树的子树大小和的最小值,转移枚举根即可。复杂度 \(O(n + (r-l)^3)\)。
CCPC 2020 绵阳
A. A Colorful Grid
考虑把相邻两个颜色相同的中间画一道障碍,考虑两个点不连通当且仅当两个点之间任何路径都要经过障碍。
可以发现,障碍一定不存在 L 形,因为 L 形的角落上存在连在一起的障碍,不符合题意。
所以两个点不连通当且仅当存在一条竖着的或横着的线切开了两个点,同理,两个点连通等价于不存在横着或竖着的线切开两个点。
注意到不可能同时存在一条竖着的切线和横着的切线,否则交点处无法构造。于是考虑对竖线和横线分别考虑是否有解。
这两类是类似的,以竖线为例,发现对于任意相邻两条竖线 \(a \leq b\),要求 \(b - a \geq 2\) 且 \(2 \mid n(b-a)\),前者表示不能存在相邻的切线,后者表示切线中间的一段数量必须为偶数。当 \(2 \nmid n\) 时,要求 \(2 \mid b-a\),则所有可选的竖线都应被选择。对于 \(2 \mid n\) 时,则只是要求不能选相邻的,此时考虑一个 DP,记 \(f_{i,0/1}\) 表示前 \(i\) 个竖线在符合要求的情况下,\(i\) 是否被选时,最后一条竖线的最大位置,转移枚举下一条选不选即可。
C. Code a Trie
把给定字符串的 Trie 建立出来,从上到下 DFS 一下贪心即可。
E. Escape from the Island
考虑拆点,对于每个点拆成 \(k\) 个点表示到了 \(u\),某轮走了 \(x\) 步的点。倒着从 \(n\) 做最短路,转移形如 \((u,i) \rightarrow (v,i-1)\) 或 \((u,0) \rightarrow (v,0)\)。每个点最多入队 \(2\) 次,复杂度是 \(O(k(n+m))\)。
F. Fracture Ray
考虑求每条射线到达的镜子位置,由于是 \(45\) 度方向,所以到达的点必然形如是 \(x+y\) 相同,并且 \(x \geq k\)。四个方向本质类似。
以向右上 \(45\) 度为例,那么 \(y-x\) 相同,对于每个镜子,可以求出 \(y-x\) 的一个区间,问题变为求一个 \(x\) 或 \(y\) 最小的镜子使得 \(y-x \in [l_i,r_i]\)。考虑离散化后建立线段树,把每个 \([l_i,r_i]\) 在线段树上拆成不超过 \(O(\log n)\) 个区间,每个线段树区间维护平衡树表示所有包含这个区间的编号集合,本质就是线段树套平衡树。总复杂度 \(O(n \log^2 n)\)。
I. Invaluable Assets
考虑朴素的 DP 是,\(f_i = \min \limits_{j} \{f_j+(i-j)^2+c\}\)。
注意到当 \(i > c\) 时,存在相同整数 \(d\) 使得 \(f(i) = f(i-d)+d^2+c\),\(d\) 在 \(\sqrt c\) 附近。
对于 \(k-h_i \leq c\) 的部分暴力,由于数据随机可以通过,\(k-h_i > c\) 的部分,枚举 \(h_i \bmod d\) 的值并将 \(h_i \bmod d\) 相同的一起统计。
CCPC 2020 长春
B. The Tortoise and the Hare
首先可以发现,选最近的 \(k\) 个其实是最优方案。
考虑把问题改成,每次可以选任意 \(k\) 个操作,显然答案不变。此时可以考虑二分答案,记二分值为 \(x\),求出 \(s = \sum \limits_{i=l}^r \max(0,a_i+x-m+1)\),判断 \(s\) 与 \(x \times k\) 的大小关系即可。
先考虑朴素实现,在外层二分,里层维护树套树,可以做到 \(O(n \log^3 n)\),考虑更厉害的一点的做法,我们直接根据线段树结构进行二分,但不同之处是我们需要维护权值线段树套主席树,然后在线段树上二分,时间复杂度 \(O(n \log n \log V)\),空间复杂度 \(O(n \log V)\)。
但是我们还有更加好写的做法。考虑离线整体二分,因为询问可以二分,并且二分判定涉及到的值是对 \(a_i\) 的一个偏序关系限制。于是每次取出目前答案区间 \([l,r]\) 的中点 \(mid\),按照时间顺序处理有效修改和询问,并递归到两个子区间即可。不再需要使用树套树而是只需要线段树或树状数组。时间复杂度 \(O(n \log n \log V)\),空间复杂度 \(O(n)\)。
C. Quantum Geometry
我们猜测走法必然是,走到一个端点,然后要么从我目前看到的那个之前被挡住的顶点那里绕过三角形,要么走到另一个端点然后走到目标点。以初始走到靠下的端点为例,可以注意到三角形第三点被限定在了这个端点出发的一个角中,并且这个角和另一个端点无关,\(O(n^2)\) 预处理这样的点对的答案即可 \(O(1)\) 回答询问,复杂度 \(O(n^2+q)\)。如果没有意识到与另一个端点无关应该也可以扫描线做到 \(O(n^2 \log n+q)\)。
F. Strange Memory
很容易想到启发式合并,过程中拆位维护一下贡献即可,复杂度 \(O(n \log n \log V)\)。
G. Monkey's Keyboard
记 \(p_i\) 为每一步打出字符 \(i\) 的概率。
我们有结论,对于一个给定的字符串 \(s\),计算 \(s\) 自身的答案,设 \(n = |s|\),则答案为 \(\sum \limits_{i=1}^n [s[1\cdots i] = s[n - i + 1 \cdots n]] \times \prod \limits_{j=1}^i p_{s_j}\),即其所有 Border 的概率乘积之和。
证明让我学习一下。
考虑对 \(s\) 的所有子串求和怎么做,建出 SAM,考虑每个状态的贡献。发现若这个状态出现 \(c\) 次,则会有 \(\dbinom{c}{2}\) 个 \(s\) 的子串包含这个 Border,并且每个贡献相同,是一段区间的 \(p\) 的乘积,把式子写出来发现你只需要维护 \(\dfrac{1}{p}\) 的区间和,以及 SAM 每个状态在字符串的任意一个结尾位置,就可以做到每个状态 \(O(1)\) 计算贡献。
H. Combination Lock
完全没有注意到啊。
每次操作都会更改数字和的奇偶性,所以这个是二分图博弈游戏,经典结论是先手必胜当且仅当起点在所有最大匹配上。求最大匹配后删点再求一次即可。
J. Abstract Painting
把圆投影成线段,要求任意两条线段要么不交要么包含。
考虑从前往后 DP,在每个线段的左端点处确定是否选择。记 \(f_{i,S}\) 表示到了 \(i\),\([i+1,i+10]\) 每个点目前是否为某个右端点时的答案即可。
K. Ragdoll
首先可以 \(O(V \log V)\) 求出所有有效对 \((x,y)\) 使得 \(x \oplus y = \gcd(x, y)\)。
可以感受到这样的有效对不是很多,所以每个数在所有对中出现次数也不会太多。
直接启发式合并时枚举加入的数 \(x\) 所在的所有对 \((x,y)\) 即可。
L. Coordinate Paper
考虑每次减 \(k\),或者加 \(1\),所以只要 \(a_1 \bmod (k+1)\) 确定,那么每个 \(a_i \bmod (k+1)\) 都唯一确定,总和 \(\bmod (k+1)\) 也确定。枚举 \(a_1 \bmod (k+1)\) 的值为 \(x\),考虑序列每个数为 \(x,(x+1)\bmod k,(x+2) \bmod k\) 时序列和取到最小值。若 \(s = \sum a_i \bmod (k+1)\) 且 \(s \geq \min \{\sum \limits_{i=1}^n a_i\}\) 必然有解。考虑构造。依次对于 \(i = 0, 1, 2, \cdots, k - 1\),将 \(a_x = i\) 的 \(x\) 修改为 \(i+k\),直至和为 \(s\)。发现到 \(k-1\) 时和若不为 \(s\),则到了 \(i=k,k+1,\cdots,2k-1\),这个过程和之前是一样的,所以可以算出 \(s\) 在第几次循环中被降为 \(0\),总复杂度 \(O(n + k)\)。
P10612
首先每条光线出口必然在入口的右上方,我们可以证明这是充要条件。
首先删去那些出口和入口同行或同列的行列,这些行列删去后显然没有影响,因为在这些行列上不能放镜子。
接着考虑归纳,\(m=1\) 时显然。考虑 \(m>1\),将最后一列射出的光线的那一行之上的所有格子都放镜子,根据光路可逆,可以归纳到 \(m-1\) 的情况。直接按照这个方式构造即可。
P4482
不会 Border 理论,考虑一些其他做法。
发现询问 \([l,r]\) 时我们即需要找到一个最大的 \(x\leq r-l\),使得 \(\operatorname{LCS}(l+x-1,r) \geq x\),其中 \(\operatorname{LCS}(a,b)\) 表示前缀 \([1,a]\) 与 \([1,b]\) 的最长公共后缀。
在 SAM 上两个前缀的 LCS 即为两个点在 Fail 树上 LCA 的 \(\operatorname{len}\)。
暴力做法是,求出 \([1,r]\) 对应前缀在 SAM 上的点 \(u\),枚举 \(u\) 的祖先点 \(p\) 并记 \(y=\operatorname{len}(p)\),考虑求出 \(l+x-1\) 这个前缀在 \(p\) 子树内时,\(x\) 的最大值。即我们要求 \(x \leq y\),然后考虑 \(p\) 子树内每个点,求出这个点对应前缀中 \(\leq \min(r-1,l+y-1)\) 的最大值。
考虑 \(u\) 到根路径上的这条链,存在一个分界点使得下面 \(\min\) 都取到 \(r-1\),上面取的都是 \(l+y-1\)。对于 \(r-1\) 的点,显然只有分界点有意义,对分界点单独做一下,就变成从这个分界点父亲到根路径上的询问了,并且每个点权 \(y\) 对应的就是 \(l+y-1\) 这个限制。
进一步优化这个算法,考虑树剖,对于到根路径,拆成了 \(O(\log n)\) 条重链上的前缀,我们对于每个前缀的最下面的这个点,也就是轻重边交换的轻边,单独计算答案,这样的复杂度是 \(O(\log^2 n)\) 的。现在对于每条重边上的前缀,考虑哪些点会对答案产生贡献。可以发现只有前缀以及前缀的轻子树内的点产生贡献,下面的点都在轻重边交换时被计算过答案。
这启发我们离线对每条重链扫描线,由于每个点的轻子树大小之和为 \(O(n \log n)\) 量级,所以对于每条重链,我们从前往后扫每个点时可以枚举轻子树内的所有点,对于每个加入的点来说,影响到的 \(l\) 是一个区间,维护线段树做区间取 \(\max\) 单点修改即可。总复杂度 \(O(n \log^2 n)\)。
P4618
怎么会有这种题的。
我们首先发现,询问 \(u,v\),考虑其 LCA 为点 \(x\),则必然有 \(u,v\) 中存在一个点与 \(x\) 的距离为 \(O(\log n)\) 级别。我们称 \(u,v\) 中离 \(x\) 较远的那条链为长链,另一条为短链。
询问 \(1\) 应该是简单的,就算数据不随机也是可以莫队的,随机的情况下,有更优的做法是,考虑直接求出长链上颜色数,对于短链上每个点判一下在长链上是否出现过即可。
询问 \(2\) 难一点,考虑两个点到根路径被分为三部分,分别是长链,短链,以及 \(x\) 到根路径。发现两个点中有至少一个点在 \(x\) 到根路径上都是好做的,因为此时两个点有祖先关系,比较容易处理。现在考虑两个点分别位于短链和长链上的情况。这时可以枚举短链上的端点 \(y\),考虑 \(y\) 与长链上所有点的路径颜色数之和怎么求。我们可以先视为 \(y\) 就是 \(x\),也就是说先对 LCA 与长链上任意一点路径颜色数求和,这个是容易做的,另一方面,对于每个短链上被包含的点,考虑算出这个点权被多或少算了多少贡献,这个也是比较简单的模型。总复杂度应该是期望 \(O(n \log^2 n)\) 的。
THUPC2025 决赛
B. 图,距离,最优化
不难看出最优方案是一条链,且应该是单谷的,其对应权值为 \(\sum \limits_{i = 1}^n \sum \limits_{j=i+1}^n a_ia_j(j-i) = \sum \limits_{i=1}^{n-1} \left( (\sum \limits_{j=1}^i a_j) \times (\sum \limits_{j=i+1}^n a_j) \right)\)。
考虑 DP,从大到小加入数,每次在目前未选区间的左端或右端加数,记 \(f_{i,j}\) 表示插入了前 \(i\) 大的后,极长被选前缀和为 \(j\) 的最大答案即可转移。复杂度 \(O(n^2V)\)。
E. 一个 01 串,n 次三目运算符,最后值为 1
考虑若存在 \(s_i = 1\),\(s_j = 1\),且 \(i\) 为奇数,\(j\) 为偶数,\(i<j\),则有解,原因是可以把中间 \((i,j)\) 这一段直接忽视,然后考虑把 \([1,i-2]\) 这段求出后进行构造。
当然有些特判,比如 \(s_n=1\),或者 \(n\) 比较小,其他情况无解。
F. 石墨烯
首先答案的上界是,按照题意模拟,直到剩下人数不超过 \(k\) 时停止,显然答案不超过这个值,应该可以猜测到这个就是答案值。
考虑怎么模拟这个过程,发现每一次有效的操作,要么 \(a_i \leq b_i\),对应 \(a_i \gets 0\),或者 \(a_i > b_i\),则 \(b_i \gets 0\),所以有效操作次数是 \(O(n)\) 级别的,目标即进行所有有效操作。
用一个优先队列按照时间维护所有操作即可。
G. 好串
考虑给定 \(s_1,s_2,s_3\),如何计算 \(f(s_1,s_2,s_3)\)。
从前往后考虑每个 \(t_i\) 是多少,发现若 \(t_i\) 为 \(s_{1/2/3,i}\) 中出现次数最大的那个,则相当于对后面的字符有一些限制,这些限制只和这次出现次数较大的那些串是什么而与其他无关,若 \(t_i\) 为出现次数少的那个,则 \(t\) 之后的值必然是对应的 \(s\) 后面的值。
于是可以从前往后进行 DP,记 \(f_{i,S}\) 表示已经填了 \([1,i]\),之前每次取的都是出现次数较大的字符,\((1,2),(1,3),(2,3)\)是否作为过出现次数最大的两个时的概率,转移 \(2^3\) 枚举所有可能情况即可。
H. 三元链
手玩可以注意到有解当且仅当 \(k \in [\dfrac{1}{2}n,\dfrac{2}{3}n]\) 或 \(n=3,k=1\)。
考虑怎么对 \(k \in [\dfrac{1}{2}n,\dfrac{2}{3}n]\) 进行合理构造。
考虑增量构造,可以先构造出 \(n=3,k=2\) 以及 \(n=2,k=1\),并且满足两种构造方式的下边界构成一样,这样即可叠加。于是可以递归填入这两种构造。
I. I’m Here
这个也太难了吧。
K. 喜爱之钥
显然主要切入点应该是每个人的策略。
\(k=0\) 时,可以假设第一个人选择第一把钥匙开第一把锁,则若这把钥匙打开了锁,递归到 \(l-1\) 的子问题,否则第二个人有两种选择:用同一把钥匙开另一把锁,或用另一把钥匙开同一把锁。由于 \(k=0\),这两种情况的概率相同并且被选择的概率也相同,不妨假设选择的方案就是用同一把钥匙开另一把锁,则要么开了锁递归到子问题,要么第三个人也会用同一把钥匙开一把前两个人没选择的锁,以此类推。于是直接设计 DP,记 \(f_{i,j}\) 表示现在轮到了第 \(i\) 个人操作,现在还剩 \(j\) 把锁,转移枚举哪个人成功用第一把钥匙开了某把锁,复杂度 \(O(nl^2)\),这个是容易优化到 \(O(n^2l)\) 或 \(O(nl)\) 的。
\(k>0\) 时,猜测每次选同一把钥匙开另一把锁总是最优决策。事实上这确实是最优策略,但这并不是唯一的最优策略,因为还可以选择另一把钥匙开同一把锁,其余情况必然不优。但是可以注意到,只要第二个人选择了两种方式中的一种,则后面的所有人都会选择同一种方式,否则无法取到最优的概率。而对于第二个人来说,选择这两种方案的概率之比为 \(\dfrac{l-1}{l+k-1}\),将 DP 状态改为 \(f_{i,j,k}\) 表示到了第 \(i\) 个人,还剩 \(j\) 把锁和 \(k\) 把假钥匙的概率。按照概率之比转移两种方案可以简单做到 \(O(n^2lk)\),注意到转移只需要做一个区间加,直接在差分数组上维护即可。复杂度 \(O(nlk)\)。
L. 列队
考虑单次询问怎么做,分析一下结果的性质。
打表或者简单分析可以看出,两个操作都最多操作 \(1\) 次,也就是说要么每行本身就已排好序,要么排序后再对列排序然后结束过程。原因也很简单,考虑如果矩阵只有 \(0\) 和 \(1\),排两次序后肯定符合条件。对于原矩阵,考虑这样操作后如果存在一行按顺序两个数 \(a,b\) 满足 \(a>b\),则将 \(\leq b\) 的数视为 \(0\),其余数视为 \(1\),导出矛盾。
于是我们只需要维护排序两次的过程,并且特判初始时行都排好序。显然判断行是否都排好序是很容易的,考虑排序两次怎么做。
这个过程看着比较困难,时限也比较大,考虑能不能做到根号之类的复杂度。这个是矩阵,显然提示我们使用 \(\min(n,m) \leq \sqrt{nm}\) 的 Trick。设定阈值 \(B\),\(m \leq B\) 时,修改时对行重新排序,然后每列维护一个数据结构支持插入删除,查询 \(k\) 小值。\(m > B\) 时,\(n < \dfrac{nm}{B}\),对每行维护同样的数据结构,查询把每行对应的值求出后直接算答案。
分析复杂度,如果使用平衡树这样的数据结构,取 \(B=\sqrt{nm}\) 可以做到 \(O(q\sqrt{nm}\log{nm})\),但无法通过。注意到 \(m \leq B\) 时,我们要做 \(O(qB)\) 次插入删除和 \(O(q)\) 次查询 \(k\) 小值,可以简单使用分块均摊两部分复杂度做到 \(O(qB)\),取 \(B=\sqrt{nm \log nm}\) 即可做到 \(O(q\sqrt{nm \log nm})\),写得好已经能过了。但可以做到更优。发现 \(m>B\) 时,要做的是 \(O(q)\) 次插入删除与 \(O(q\dfrac{nm}{B})\) 次查询,我们希望能做到 \(O(\sqrt{nm})\) 插入和 \(O(1)\) 查询。这个是可以维护的。具体地,插入删除对第 \(k\) 小的数构成的序列的影响是类似于区间位移一格的操作,分块并对每个块维护链表即可支持这样的操作,总复杂度即可做到 \(O(q\sqrt{nm})\)。
PKUWC2025 Day1
T1 电池检测
考虑询问了 \((x,y)\) 就连边 \(x,y\),得到了一张 \(a+b\) 个点的无向图,我们希望图中的边尽量少,并且使得图中的最大独立集数量不超过 \(a-1\),因为若 \(\geq a\) 则最大独立集中任意两点没有连边,不符合要求。
然后注意力敏锐或者打个表可以发现整个图应该是若干个完全图构成。直接对这个 DP 可以得到 \(O(n^3)\) 的做法,应该是可以通过的。进一步可以看出这些团大小应该尽量平分,所以可以做到更优的复杂度。
T2 Ancestors
考虑如果每次询问的 \(x\) 都一样,这个问题是区间数颜色,我们肯定希望维护出 \(pre_i\) 表示最大的 \(j<i\) 使得 \(c_j = c_i\),然后变成查询区间中有多少 \(pre_i < l\)。
我们仍然考虑维护 \(pre_i\),具体地应该是维护 \(pre_{i}(x)\) 表示在询问为 \(x\) 的情况下的 \(pre_i\) 为多少。
离线下来,按 \(x\) 扫描线,我们希望 \(x \gets x + 1\) 时能更新所有 \(pre_i(x)\)。
首先我们给出结论,所有 \(pre_i(x)\) 的变化总次数为 \(O(n \log n)\) 量级。具体地考虑这样的过程:显然 \(pre_i(x)\) 的深度必然和 \(i\) 的深度相同,否则 \(x\) 级祖先深度必然不同。对于每个深度 \(d\) 单独考虑所有 \(dep_i=d\) 的点,发现 \(x\) 逐渐增加的过程本质是,初始有一个集合 \(S\),包含所有 \(dep_i = d\) 的点,\(x\) 每增加 \(1\),集合内每个点变为其父亲,然后将相同位置的集合合并。考虑集合合并的过程中,\(pre_i(x)\) 更改的原因是向一个集合中插入一个数,会改变 \(O(1)\) 个点的前驱。又由于整个过程可以启发式合并,于是向集合内插入数的总次数是 \(O(|S| \log |S|)\) 量级,总次数是 \(O(n \log n)\) 量级。
然而我们还需要将所有这样的变化位置找出,直接在原树上 DFS 时做启发式合并应该是可以的,还有一个做法是直接对深度相同的点按 DFN 序排序维护所有有效合并。
现在问题变成,\(O(n \log n)\) 次单点修改,\(O(m)\) 次区间查询 \(< l\) 的数的个数。直接 CDQ 分治即可做到 \(O(n\log^3n + m\log^2 n)\),常数比较小应该能过。
还有一个莫队做法,大概意思是考虑对同层的所有在区间内的点建虚树,查询变成了深度大于等于 \(x\) 的最小在虚树上存在的深度的点数,莫队的时候可以按照 DFN 序维护有序集合每次往里面插数并维护虚树上的点集合。复杂度 \(O(n \sqrt m \log n)\),据说可以回滚莫队做到 \(O(n \sqrt m)\),但是未必跑得过 CDQ 分治。
T3 基础博弈练习题
好题啊!
下文 \(u \rightarrow v\) 指的是 \(u\) 能到达 \(v\)。
先考虑图是 DAG 怎么做,首先有一个 \(O(n^2)\) 做法,记 \(f_{u,i}\) 表示点 \(u\) 为起点,第 \(i\) 局开始,先手能否获胜。转移形如 \(u \rightarrow v, a_v = b_i, f_{v,i+1}=0\) 的 \(v\) 而来。为了做到更优的复杂度,考虑能不能只维护一维信息,即直接考虑对于每个点 \(u\) 求 \(g_u\) 表示答案,即最小的 \(i\) 使得 \(f_{u,i} = 1\)。
考虑能不能快速求出 \(g\),首先可以发现如果 \(u \rightarrow v\),则 \(g_u \leq g_v\),然后考虑 \(u\) 有没有可能小于所有 \(g_v\),此时需要有一个 \(u\rightarrow v\) 和 \(i\) 使得 \(a_v = b_i,f_{v,i+1}=0\),并且这个 \(i\) 有意义的必要条件是 \(g_v > i + 1\)。所以对于每个 \(v\),若 \(g_v > i + 1\) 且 \(b_i = a_v\),则 \(g_u \gets \min(g_u, i)\)。显然的这个 \(i\) 应该是最小的满足 \(b_i = a_v\) 的 \(i\),所以记 \(pos_j\) 表示最小的 \(i\) 使得 \(b_i = j\),则对于每个 \(v\),有意义的 \(i\) 只有 \(pos_{a_v}\),所以若 \(g_v > pos_{a_v} + 1\),则 \(g_u \gets \min(g_u,pos_{a_v})\)。这个在拓扑排序的过程中可以简单维护做到 \(O(n+m+k)\)。
考虑图不是 DAG,容易看出每个 SCC 的答案应该相同,所以先缩点。在缩点的 DAG 上,上面的两个转移是类似的,只不过要对 SCC 内的每个 \(v\) 记录第二类转移的贡献。但是还有一个转移是 SCC 内部可能存在有效转移,即考虑一个 SCC 内颜色集合为 \(S\),考虑其内的一个点 \(u\) 满足 \(f_{u,i+1} = 0\),且 \(b_{i} \in S\),则 \(f_{u,i} = 1\)。有一个平方做法是,对于每个非单点的 SCC,从大到小枚举每个 \(i\),若 \(b_i \in S\) 且 \(g_u > i + 1\),则 \(g_u \gets i\)。
然后考虑怎么优化复杂度。考虑对于这样的 SCC,最终的 \(g_u\) 到底是多少,可以发现求出最小的 \(i\) 使得 \(b_i \in S\),则最后一步要么 \(g_u > i + 1\),则 \(g_u \gets i\),否则 \(g_u = i + 1\),所以结果必然是 \(g_u = i\) 或 \(g_u = i + 1\)。所以只需要考虑 \(g_u\) 到底是 \(i\) 还是 \(i+1\)。记 \(w\) 为对 SCC 进行转移前的 \(g_u\),发现如果能找到最小的 \(j>i\) 使得 \(b_j \notin S\) 或者 \(j = w\),则 \(g_u\) 到底是 \(i\) 还是 \(i+1\) 只取决于 \(j\) 和 \(i\) 的奇偶性。那么你只需要对每个 SCC 求出 \(j\) 即可,因为 \(i\) 是很好求的。考虑对于每个 \(x\) 求出 \(pre_x\) 表示上一次和 \(b_x\) 相等的位置,从 \(i\) 开始线段树二分,每次找到第一个 \(pre_x < i\) 的 \(x\),若其出现过则继续这个过程,显然每种颜色只会被访问一次,总复杂度是一个 \(\log\) 的。
CF1542E2
首先容易求出 \(f_{i,j}\) 表示有多少长度为 \(i\) 的排列有 \(j\) 个逆序对,考虑枚举两个排列的 LCP,容易得到一个 \(O(n^7)\) 的做法,这个前缀和优化一下可以得到 \(O(n^4)\),对这个再推一下式子发现事实上你需要维护一个前缀和的前缀和以做到 \(O(n^3)\)。
CCPC Final 2020
A. Autobiography
枚举中间那条边就可以简单计算了。
D. Data Structure
有点深刻了。
看起来可能需要建图,考虑每个球视作一个点,向其同色的另一个球以及同栈的另一个球连边,则每个点度数要么为 \(1\) 要么为 \(2\),考虑依次消除每个连通块。
每个连通块会是一条链或一个环,对于链来说考虑其什么时候能不借助空栈消完,这等价于不存在某种颜色的两个球同时处在栈顶。若不能消完则必须借助一个空栈,然后每次将最链上最左侧的同色栈顶球拉出来,左侧必然是好链,右侧可以继续构造。
对于环,必须借助空栈,选择一条边断开即可。由于要尽可能使得断边后得到的是能消完的链,需要分类讨论同色栈顶球对数。然后容易看出为了留出尽量多的空栈应该先做链再做环,对于链应该先做不用借助空栈的链再做其他链。
E. Game Theory
考虑这个过程是什么。
求出原串中 \(1\) 的数量,记为 \(k\),不妨假设 \(s_k = 0\),\(s_k = 1\) 是同理的,则这个过程是先往右找到第一个 \(1\),然后往左找到第一个 \(0\),重复这个过程。
于是你只需要求出 \(k\) 后往左往右查询一下 \(0,1\) 的数量和下标和即可。线段树维护一下即可。
G. Hamilton
等价于你要在这个边权为 \(0\) 或 \(1\) 的无向完全图中求一条哈密顿路径,使得写下的边权序列一段前缀是 \(0\),后面全都是 \(1\)。
考虑增量构造,你之前有一条起点和终点分别为 \(u,v\) 的合法路径,加一个点 \(x\),若 \(u,x\) 边权为 \(0\) 或 \(v,x\) 边权为 \(1\) 则直接连上去,否则你考虑 \(u,v\) 这条边权是 \(0\) 还是 \(1\),都可以绕一圈过去,所以必然有解。
H. Nonsense
神题。
这个式子太难看了,给他编个组合意义吧。
有 \(n+1\) 个球,三种颜色,分别是黑、白、蓝。蓝球恰有一个,枚举它在第 \(i+1\) 个位置,要求左侧恰有 \(a\) 个黑球,右侧恰有 \(b\) 个白球,且左侧每个白球贡献为 \(x\),右侧每个黑球贡献为 \(y\),则对应值则为 \(\dbinom{i}{a}x^{i-a}\dbinom{n-i}{b}y^{n-i-b}\)。
现在对这个式子可以递推了。考虑左侧的球是黑色还是白色,则有 \(f_{n,x,y}(a,b)=f_{n-1,x,y}(a-1,b)+xf_{n-1,x,y}(a,b)\)。另一方面,考虑右侧的球是黑色还是白色,有 \(f_{n,x,y}(a,b)=f_{n-1,x,y}(a,b-1)+yf_{n-1,x,y}(a,b)\)。则两式求差可知 \(x \neq y\) 时,\((y-x)f_{n-1,x,y}(a,b)=f_{n-1,x,y}(a,b-1)-f_{n-1,x,y}(a-1,b)\),于是可以对 \(a,b\) 递推。
\(x=y\) 时,原式等于 \(x^{n-a-b}\sum \limits_{i=a}^{n-b} \dbinom{i}{a} \dbinom{n-i}{b}\)。后面的等于 \(\dbinom{n+1}{a+b+1}\),直接计算即可。
I. Number Theory
有一个三次方是,你发现每一位不可能选超过 \(10\) 个,否则可以更优。所以一个 DP 是十进制从左往右,\(f_{i,j,k}\) 表示到了第 \(i\) 位,之前选了总共 \(j\) 个,要求下一位往前进位 \(k\) 次。然后这个东西似乎是需要一个高精度才能做到三次方,但我还不会平方啊。
J. Permutation Pattern
求合法子序列个数一般是从前往后加入,但这个题直接这么做很困难,因为你考虑这个题对于子序列从前往后加入数进行判定是比较难的,相当于是你在加入 \(x\) 的时候,限制是对于任意 \(y\) 不为之前的后缀最大值,要求 \(x>y\)。但是你在 DP 状态中难以维护这个后缀最大值集合。
考虑另一个判定子序列的方式,类似于建出笛卡尔树,每次按最大值把序列分为左右两部分,要求左右两部分本身合法的前提下,左侧任意数小于右侧任意数,即左侧最大值小于右侧最小值。
所以有一个很直接的区间 DP,\(f_{i,j,k,l,0/1}\) 表示在区间 \([i,j]\) 中选子序列,要求选的数在 \([k,l]\) 之间,\(l\) 是否强制要求被选。转移枚举最大值位置和左侧最大值位置即可做到 \(O(n^6)\),看着过不去但是你仔细分析一下状态数发现常数非常小,事实上这个不超过 \(200\) 毫秒就过了。
K. Stringology
考虑这个 \(\operatorname{presuf}(s,\operatorname{pre}(s,i)+t)\) 是什么,要么其值小于等于 \(|t|\),此时应该是等于 \(\operatorname{presuf}(s,t)\),或者其值大于 \(|t|\),则你的要求是 \(s\) 这段前缀的长度为 \(|t|\) 的后缀为 \(t\),然后前面这部分是和 \(\operatorname{pre}(s,i)\) 的一段后缀相同。枚举 \(s\) 中所有和 \(t\) 相同的子串,考虑要求是前面这段是 \(\operatorname{pre}(s,i)\) 的后缀,这显然是 Fail 树的子树,于是直接在 Fail 树上统计一下即可。
L. 2D Geometry
等价于你每次删掉不共线的三点,所以你最后剩下的必然是所有点共线。
考虑选出一条点数最多的线,记其上给定点数为 \(c\),考虑 \(c \leq \dfrac{2n}{3}\) 时,必然有你每次可以选线上两点和线外一点递归到 \(n-3\) 的情况,所以必然能选满 \(n - n \bmod 3\) 个点。否则 \(c > \dfrac{2n}{3}\),这时贪心策略很容易。所以目标是求出这个 \(c\)。发现由于 \(c > \dfrac{2n}{3}\),考虑随机化,每次随机两个点把在这条线上的点求出计算数量即可。
CCPC 2021 桂林
B. A Plus B Problem
直接对求和的结果进行维护,显然的,对一个位置加 \(1\) 等价于往左找到第一个不为 \(9\) 的位置,然后这个值 \(+1\),区间覆盖 \(0\)。减法是对称的。
直接线段树二分维护这个过程即可。
H. Popcount Words
这个题挺牛。
考虑 \(s_i = \mathrm{popcount}(i) \bmod 2\) 到底是一个什么序列。这个是一个比较经典的问题,这个序列本质是,\(s_0 = 0\),每次对于目前字符串 \(s\),将 \(\mathrm{flip}(s)\) 加在 \(s\) 末尾。
记 \(S_{i,0/1}\) 表示区间 \([0,2^i)\) 或 \([2^i,2^{i+1}-1)\) 的字符串,我们发现字符串区间 \([k2^i, (k+1)2^{i}-1]\) 其实就等于 \(S_{i,\mathrm{popcount}(k) \bmod 2}\),这个通过归纳容易看出。
考虑将一个字符串区间 \(s[l,r]\) 用若干 \(S_{i,0/1}\) 表示,发现只需要对于目前的 \(l\),找到最大的 \(k\) 使得 \(l+2^k-1 \leq r\) 且 \(l \equiv 0 \pmod {2^k}\)。容易发现每个 \(s[l,r]\) 可以用不超过 \(O(\log V)\) 个 \(S_{i,0/1}\) 表示。
对询问串建立 AC 自动机,我们希望求出给定串在 AC 自动机上匹配的过程中经过每个点的次数。我们将其拆成 \(O(n \log V)\) 个 \(S_{i,0/1}\) 拼接的形式,容易对于自动机每个点 \(u\) 求出 \(f_{u,i,0/1}\) 表示在 \(u\) 开始,经过 \(S_{i,0/1}\) 这个串到达的节点,可以发现 \(f_{u,i,j} = f_{f_{u,i-1,j},i-1,1-j}\)。现在考虑怎么求每个点被经过的次数,考虑把 \((u,i,0/1)\) 这个状态的转移边画成 DAG,本质上就是每次从一个 \((u,i,j)\) 出发,递归经过 \((u,i-1,j)\) 和 \((f_{u,i-1,j},i-1,1-j)\)。直接对于每个 \((u,i,j)\) 统计这个点出发了多少次,在 DAG 上做一个拓扑排序即可。总复杂度 \(O((n+\sum |p_i|) \log V)\)。
J. Suffix Automaton
建出 SAM,对每个状态长度区间 \([l,r]\) 做区间加 \(1\) 即可求出每种长度的本质不同子串个数,于是可以简单求出询问串的长度,问题变为给定 \(x,k\),求长度为 \(x\) 的本质不同子串中字典序排名第 \(k\) 个的首次和末次出现位置。
可以在 SA 上刻画这个东西,离线对 \(x\) 扫描线,\(x \gets x - 1\) 的过程中,会有一些排名相邻的子串合并为一个,直接维护一个平衡树即可查询出排名为 \(k\) 的是哪一个了。
K. Tax
神秘题。
看着就不可做,考虑一些非多项式复杂度乱搞。
求出 \(1\) 到每个点的最短路 \(d_i\),发现只需要保留 \(d_j = d_i + 1\) 的边,并且边是有向的。
直接在这个有向图上爆搜即可通过。
考虑分析复杂度,记第 \(i\) 层的点有 \(c_i\) 个,发现路径数量为 \(\sum \limits_{i} \prod \limits_{1 \leq j \leq i} c_j\),最坏情况是所有 \(c_i = 3\),复杂度不超过 \(O(3^{\frac{n}{3}})\)。
L. Wiring Engineering
UOJ153
https://peehs-moorhsum.blog.uoj.ac/blog/6272
CF1685E
这个题也太牛了!
根据 Dilworth 定理,一个排列的 LIS 长度不超过 \(n\),等价于存在一种方案使得可以将排列分为不超过 \(n\) 个下降子序列。
考虑这个东西的一个必要条件,如果能将排列分为若干个长度至少为 \(2\) 的下降子序列,则天然满足数量不超过 \(n\),虽然这不是充分条件,但是可以给我们一些启发。
只考虑长度为 \(2\) 的下降子序列,若忽略排列中 \(n+1\),将 \(>n+1\) 的数视为 \(1\),将 \(<n+1\) 的数视为 \(-1\),则本质等价于括号匹配,我们需要做的是把排列循环移位使得所有前缀和非负,显然画出折线图可以看出选最下的点作为起点即可,这样一定有合法括号匹配。
考虑加入 \(n+1\) 时会发生什么,此时这个数如果在某对匹配的括号之间,可以直接在这个括号之间加入这个数,否则其必然处于括号匹配段之外,此时考虑两种循环移位,分别是 \(n+1\) 为开头或 \(n+1\) 为末尾,这两种若都不符合条件,则必然是以 \(n+1\) 为开头时,\(n+2\) 到 \(2n+1\) 递增排列,\(1\) 到 \(n\) 也递增排列,这种情况必然无解,因为你在任意一个位置断开都可以选后面的若干个 \(<n+1\) 的数和 \(n+1\) 和前面 \(>n+1\) 的数,LIS 必然超过 \(n\)。
带修的维护是比较简单的,具体地,判定 \(n+1\) 是否在匹配括号内部只需要判断从 \(n+1\) 所在位置开始时是否所有前缀和都非负,而判定其余数是否递增排列是很容易的,线段树维护即可,总复杂度 \(O(n \log n)\)。
2025.4.18 NOI 模拟赛
T1
对右端点扫描线,变为求区间中 \(1\) 的位置的权值和,维护最小值和次小值以及对应的权值和即可。
T2
考虑确定其中一条路径 \(u,v\),那么另一条路径的方案数应该是考虑这条路径把树分成了若干个连通块,答案是每个连通块的 \(\sum \limits_{x} \dbinom{cnt_x}{2}\) 之和,\(cnt_x\) 表示这个连通块中 \(x\) 出现次数。
考虑弱化问题,\(q\) 次询问 \(u,v\),求这个 \(\sum \limits_{x} \dbinom{cnt_x}{2}\) 的和。这个东西是可以做的。考虑求出 \(\mathrm{LCA}(u,v)=l\),求出 \(u,l\) 的答案和 \(v,l\) 的答案,减去将 \(v\) 删掉后每个连通块的 \(\dbinom{cnt_x}{2}\) 的和即可。
考虑怎么求 \(u,l\) 的答案。
对于每个点求出到根的答案即可简单计算这个东西。这个过程可能需要 Dsu on tree,但都是 trival 的。
使用 \(O(1)\) LCA 可以做到 \(O(1)\) 查询 \(u,v\) 两点答案。
现在考虑对于每个点 \(u\) 求出路径端点为 \(u\) 的方案数。考虑点分树上统计这个信息就好了。总复杂度 \(O(n \log n)\)。
T3
广东省集 Day0
试机赛。
T1
这个题真难吧。
猜策略完全猜不对,考虑把问题变得形式化一点。设分了 \(k\) 次,对于每个石子赋一个长度为 \(k\) 的 01 串,第 \(i\) 位 \(1\) 表示其在第 \(i\) 次操作被选择分开,则要求对于每个 \(1 \leq i \leq k\),第 \(i\) 位为 \(1\) 的数量不超过 \(m\),且每个石子标号不同。
二分答案 \(k\),判定每个石子填入 \([0,2^k)\) 中的数是否可行。
这个策略是,从小到大枚举 \(c = \mathrm{popcount(i)}\),则可以为 \(\dbinom{k}{c}\) 个数产生贡献。可以证明在这些数和到达 \(n\) 时若 \(1\) 的总数量不超过 \(nm\) 则可行否则不可行,但为啥啊???
DengDuck 大神告诉了我原因,大概是说每一位的所有 \(1\) 是独立的,所以只要总和没爆就能平均分,太牛了!
T2
本质不同排列不好刻画,考虑将问题双射成合法的选择不交区间数量,但是可能算重。
考虑对一个区间 \([l,r]\) 排序什么时候是可以被替代的,若存在 \(l \leq i < r\) 且 \(\max \limits_{j=l}^i p_j < \min \limits_{j=i+1}^r p_j\) 则可以被两次操作 \([l,i]\) 和 \((i,r]\) 代替,显然不存在这样的 \(i\) 的区间不能被替代。于是问题等价于选择若干不交的不存在划分点的区间的方案数。
这个是很容易 DP 的,暴力大概是 \(f_i\) 表示最后一个区间结尾为 \(i\) 的方案数,发现整个转移是很容易用单调栈刻画的,只需要维护线段树即可。
广东省集 Day1
原题大赛。
T1
对于每条边,若 \(a>b\),加入 \((u,v,a,0)\) 和 \((u,v,b,-1)\) 的边,否则加入 \((u,v,a,1)\) 和 \((u,v,b,0)\) 的边,分别代表初始时认为选的是 \(a\) 还是 \(b\),然后从前往后 DP,对于每条边考虑其选不选,若选,则 A 类边数量加上对应的权值,然后更新并查集。总复杂度 \(O(m^2\mathrm{Bell}(n))\)。
T2
考虑暴力怎么做,肯定是求离散对数后把乘法变成求和,然后变成了模意义 01 背包判定问题,直接 bitset 是 \(O(\dfrac{n^2}{\omega})\) 的。
一个错误的想法是考虑用 poly 优化这个东西,事实上并没有前途。
有一个非常厉害的做法,考虑每次往背包里加一个数 \(x\),本质是连有向边 \(i \rightarrow (i+x) \bmod (p-1)\),所以整个图是若干个环。考虑所有 \(f_i =0\) 且 \(f_{(i + x) \bmod (p-1)} = 1\) 的边,必然在之后有一个 \(f_j = 1\) 且 \(f_{(j+x)\bmod (p-1)}=0\) 的边,所以形如 \(01\) 和 \(10\) 的边数量相同,而 \(10\) 的边总数是 \(O(n)\) 的,所以每次更新找出 \(f_i \neq f_{(i + x) \bmod (p-1)}\) 的 \(i\) 即可,断环为链,每次二分找到下一个,用个 DS 维护区间哈希即可。总复杂度 \(O(n \log^2 n)\)。
T3
见过原题还是不会,没救了。
把每个点画在 \((i,p_i)\) 处,考虑在二维平面内刻画这个过程。
可以注意到每个点的邻点为其左上角和右下角的点。
对于一个点 \(x\),考虑将贡献改成 \(\sum \limits_{y} \sum \limits_{k} [dis(x,y) \geq k]\),然后考虑刻画 \(dis(x,y) \geq k\) 的 \(y\) 到底是怎么样的。可以发现点 \((x,p_x)\) 把平面分成四部分,左上和右下不用考虑,而左下和右上是独立的。以左下为例,发现最短路必然形如每次扩展左边界和下边界,即初始时有数对 \((x,x)\),每次从 \((x,y)\) 变成 \((l_y,r_x)\),然后贡献是一个矩形内点的数量,整个路径是若干不交折现形态,这个画出图很容易理解,于是直接模拟整个过程并预处理每个矩形内点数即可做到 \(O(n^2)\)。
然后我们声称对于每个点对 \((x,x)\) 不断跳这个过程,经过的所有点的数量为 \(O(n \sqrt n)\) 量级。证明大概是说,首先对于所有非平凡点对 \((x,y)\) 有 \(x<y\) 且 \(p_x > p_y\),然后考虑对于每个 \(x\),将所有 \(y > x\) 且 \(p_y < p_x\) 的 \(y\) 按照 \(p_y\) 排序,考虑前 \(\sqrt n\) 个点和后面的所有点。每次走到一个 \((x,y)\) 使得 \(y\) 为后面的点时,由于下一步 \(y\) 必然会变成 \(y>x\) 且 \(p_y\) 最小的点,所以 \(p_y\) 至少减少了 \(\sqrt n\),而 \(p_y\) 在过程中递减,所以经过不好的点数量不超过 \(O(n \sqrt n)\),而好点数量也不超过 \(O(n \sqrt n)\),所以总数是 \(O(n \sqrt n)\) 级别的。
考虑怎么求出所有有效点对,直接从每个点开始记搜,遇到经过的就停止即可。
求出有效点对后问题变为 \(O(n \sqrt n)\) 个矩形数点,然后树上统计到根路径和即可。矩形数点是容易的,扫描线时分块维护 \(O(n)\) 次单点加和 \(O(n \sqrt n)\) 次区间查询即可。总复杂度 \(O(n \sqrt n)\)。
广东省集 Day2
T1
赛时写的被卡常了,赛后还是卡不过去,怎么回事呢?
暴力做法是,你考虑第二种攻击只会有 \(k\) 次,所以枚举 \(x\) 表示最大的被操作 \(2\) 消耗的值,则花费 \(\geq x\) 的前 \(k\) 小的 \(c\) 之和以及 \(b>x\) 的 \(a\) 之和。
考虑把 \(b\) 排序,则要求选择一段后缀,花费其 \(\sum a\) 以及范围内 \(c_i\) 中的前 \(k\) 小数和。
把问题改成 \(\sum a\) 加上选 \(k\) 个 \(c_i\) 求和,考虑线段树维护这个东西。具体地,线段树每个节点维护 \(f_i,g_i\) 表示子树内选 \(i\) 个 \(c\) 的最小值,以及子树内前 \(i\) 小的 \(c\) 的和。\(g\) 是凸的所以可以直接闵可夫斯基和,转移 \(f\) 形如 \(f_i = s + \min \limits_{j+k=i} \{f_{ls,j} + g_{rs,k}\}\),后面是凸的,有决策单调性,分治即可。
分析复杂度,每个点的 \(i \leq \min(r-l+1,k)\),所以总复杂度 \(O(qk \log n \log k)\),被卡常了,但是 std 也是这个。
T2
T3
不懂。
广东省集 Day3 - DP 计数选讲 by fsz
P11835
P9171
P6836
对于固定的 \(y\) 考虑其什么时候符合条件。
记 \(y_i\) 表示 \(y\) 二进制第 \(i\) 位。从低到高考虑,不难看出必要条件是对于所有 \(i\),\(\sum \limits_{j = 0}^i 2^jy_j \times x\leq \sum \limits_{j=0}^i 2^ja_j\),进一步不难归纳其充分性。
根据 \(a\) 和 \(x\) 可以对每个 \(i\) 求出 \(\sum \limits_{j=0}^i 2^jy^j\) 的上界,记作 \(l_i\),然后考虑从高到低 DP,具体地记 \(f_{i,j}\) 表示第 \(i\) 位右侧所有数都填完了,包含其自己的左侧的和不超过 \(j\) 的可行填法,则转移考虑 \(y\) 这一位是否为 \(1\),分别从 \(f_{i-1,j}\) 和 \(f_{i-1,j-2^i}\) 转移。复杂度看似不对,实则考虑 \(j \geq 2^{i+1}-1\) 时没有意义,可以认为 \(j = l_i\)。所以若 \(j \geq 2^i\),则 \(f_{i-1,j}=f_{i-1,l_{i-1}}\),从低到高位处理 \(g_i = f_{i,l_i}\) 即可,单词复杂度 \(O(k^2)\)。
CF1603E
这个题性质比较多,需要逐步分析。
容易发现,将序列排序后,只需要检测每个前缀是否可行。
假设 \(a_1 \leq a_2 \leq \cdots \leq a_n\),枚举 \(a_1\),直接设计 DP 容易得到一个多项式复杂度算法,但是 \(n\) 上的次数太高了没法优化。
考虑这个值域为 \([1,n+1]\) 肯定有其作用。发现 \(a_1 \times a_n \geq \sum \limits_{i=1}^n a_i \geq na_1\),所以 \(a_n \geq n\)。\(a_n = n\) 时,不等号要取等,即 \(a_1 = n\)。\(a_n = n + 1\) 时需要进一步分析。
类比 \(a_n \geq n\),可以发现对于所有 \(i\) 都有 \(a_i \geq i\),然后有一个很牛的观察:若 \([1,n]\) 符合条件且 \(a_i \geq i+1\),则 \([1,i]\) 合法。这个原因是考虑 \(a_1 \times a_i \geq (i+1) \times a_1 = (n+1) \times a_1 - (n-i) \times a_1\),同时 \(\sum \limits_{j=1}^i a_j \leq \sum \limits_{j=1}^n a_j - (n-i) \times a_1\),而 \((n+1) \times a_1 \geq \sum \limits_{j=1}^n a_j\),所以两边减去 \((n-i)a_1\) 即得结论。
若 \(a_i = i\),类似地,要求 \(a_1=i\),于是一个 \(a_n=n+1\) 的序列合法等价于:
-
\(\forall 1 \leq i \leq a_1, a_i \geq a_1\)。
-
\(\forall a_1 < i \leq n, a_i\geq i+1\)。
-
\((n+1)a_1 \geq \sum \limits_{j=1}^n a_j\)。
最后一个式子等价于 \(\sum \limits_{j=1}^n (a_j - a_1) \leq a_1\)。
考虑 \(a_1\) 确定后的 DP,记 \(f_{i,s,k}\) 表示填入了 \(a_1\) 到 \(a_i\),\(\sum \limits_{j=1}^i (a_j - a_1) = s\),下一次填 \(k\) 的方案数,转移枚举填入 \(c\) 个 \(k\),有 \(s + c(k-a_1) \leq a_1\),所以是调和级数的,这个 DP 的复杂度是 \(O(n^3 \ln n)\) 的。
枚举 \(a_1\) 后复杂度是 \(O(n^4 \ln n)\),但是可以注意到 \(a_1 < n - O(\sqrt n))\) 时方案数为 \(0\),原因是 \(a_n = n + 1\) 且 \(\sum \limits_{j=1}^n (a_j-a_1) \leq a_1\),前者取到最小值时大概形如 \(a_1,a_1,a_1,\cdots,a_1,a_1+1,a_1+2,\cdots\),根据等差数列求和可以推出这个范围,所以总复杂度 \(O(n^{3.5} \ln n)\),可以通过。
P8386
考虑怎么判定一个序列合法,这个只能 DP,记 \(f_i\) 表示长度为 \(i\) 的前缀能否删空,转移枚举 \(a_j = a_i\),从 \(f_{j-1}\) 转移。
考虑把这个东西放在计数 DP 上,由于值域内所有数本质等价,所以记 \(g_{i,j,0/1}\) 表示到了 \(i\),有多少个 \(c\) 使得存在 \(a_x = c\) 且 \(f_{x-1}=1\),\(f_i\) 的值为多少,转移考虑 \(a_{i+1}\) 选的是 \(j\) 个数内的或外的即可。
AGC022E
考虑判定性问题怎么做。
从前往后维护一个序列,这个序列必然满足前面是一段 \(1\),后面全都是 \(0\)。
考虑加入一个数 \(x\),若 \(x=0\),将其放入末尾,若 \(0\) 的数量大于 \(3\) 则合并一次。否则 \(x=1\),若末尾为 \(1\),放入末尾,否则末尾必然为 \(0\),此时 \(0,1,x\) 中位数必然为 \(x\),可以把 \(0,1\) 同时删去。
所以 \(0\) 的数量不超过 \(2\),而同时可以发现若 \(1\) 的数量大于等于 \(2\) 则必然有解,所以任意时刻序列长度是 \(O(1)\) 级别的。
对于原问题,直接把 \(i\) 时刻序列中 \(0,1\) 数量记入状态即可。复杂度 \(O(n)\)。
QOJ10330
思考一下。
P9479
考察限制本质是什么,限制一要求的是前 \(n\) 个点在树上构成的虚树为这 \(n\) 个点,第二个限制等价于对于所有 \(i\),编号为 \([1,i]\) 的点在树上构成的虚树中编号最大的点的编号不超过 \(i+k\)。
按照编号从小到大加入每个点并维护虚树,初始时是给定 \(n\) 个点的树,每次加入一个点时有三种可能,分别是挂在一个点下面,加入一条边中间,或者在某条边中间开一个点并把当前点挂在下面。前两种显然只和目前虚树点有关,而第三种只和 \([i+1,i+k]\) 中还有多少点没被加入有关,所以任意时刻树的形态不重要,于是考虑直接 DP,\(f_{i,S}\) 表示加入了 \([1,i]\) 的点,\(S\) 为 \([i+1,i+k]\) 中每个点是否被之前的操作三占据时的答案,转移很简单,总复杂度 \(O(mk2^k)\)。
AGC064D
不懂。
AGC069D
考虑 \(x_i\) 等于什么,按照编号从 \(1\) 到 \(n\) 加入每个点,每次加入点将其染成黑色,则 \(x_i\) 等于插入 \([1,i]\) 后树上同色连通块数量减 \(1\)。
考虑判定一个 \(x_1,x_2,\cdots,x_{n-1}\) 是好的怎么办,由于树形态任意所以其实操作比较灵活,考虑 \(x_i\) 变为 \(x_{i+1}\) 的过程,发现整个过程中只需要维护黑色点连通块数量,分类讨论 \(x_i\) 变为 \(x_{i+1}\) 的增减情况即可。
然后把这个东西套到计数 DP 上,\(f_{i,j,k}\) 表示插入了 \([1,i]\),目前有 \(j\) 个黑色连通块和 \(k\) 个白连通块方案数即可。复杂度 \(O(n^3)\)。
CF924F
逆天题。
考虑给定 \(n\) 怎么求 \(f(n)\),这个显然是背包,然后可以注意到背包的值域上界不会很大,大概只有 \(9 \times 18\) 的一半,这个是因为最终答案不超过 \(9\),所以比一半超过 \(9\) 之后就减不回来,所以上界不超过 \(90\)。然后你把这个 DP 拉出来搜一下状态数发现没多大,然后就过了???
当然你可以跑个 DFA 最小化,这样就更对了。
P8194
重写一次题解。
判定性问题做法是,从前往后 DP,相当于是划分为若干段,每段对应集合相同,且符合题意限制。
发现转移是 \(f_i\) 从 \(f_{i-4},f_{i-2},f_{i-1}\) 转移而来,于是计数 DP 有个暴力是,记录末尾的三个数字以及四个 \(f\) 的值,状态数太大过不去。
然后可以把很多无用状态合并,这个是根据题意的一些分析,比较繁琐,反正最终能做到一个比较少的状态数。
AGC035F
考虑刻画一个什么样的序列 \(x_1,x_2,\cdots,x_n\) 和 \(y_1,y_2,\cdots,y_m\) 是可以被替代的。容易发现如果存在 \(i\) 使得 \(x_i = j\) 且 \(y_j = i - 1\) 则可以替换成 \(x_i = j - 1, y_j = i\)。
然后我们声称只需要计算有多少不存在 \(x_i = j, y_j = i - 1\) 的序列即可。这个是因为你可以考虑两种序列 \((x,y)\) 和 \((x',y')\) 如果得到的矩阵一样但均不存在上述的这样情况,那么你找出第一个 \(i\) 使得 \(x_i \neq x'_i\),然后你分析一下发现除非这个位置是之前的不好的位置,否则两个矩阵不可能一样。
对这个计数是很简单的,因为你发现每个不符合条件的 \(i\) 至多对应一个 \(j\),\(j\) 同理。所以考虑直接做二项式反演,枚举钦定了 \(i\) 个位置,然后组合数算一下,乘 \((-1)^i\) 容斥系数就行。
CF1679F
CF1740F
AGC008F
QOJ5016
广东省集 Day4
T1
考虑把删去最少改为保留最多,即求一个大小最大的集合 \(S\) 使得 \(S\) 内任意两点在两棵树上的祖先关系相同。
将可以同时存在于集合 \(S\) 的两个点之间连边,转化成求无向图最大团。\(n \leq 40\),直接搜或者随机排列从前往后贪心即可。
T2
这个为啥是黑啊?
考虑无修改怎么做,这个是很简单的斜率优化 DP。
有修改时,枚举 \(x\) 被选择的区间 \([l,r]\) 包含,列出一个式子,这个式子大概形如 \(a_l + b_r - 2 \times c \times l \times r\),要让这个东西最大。
考虑分治,对于分治区间 \([l,r]\),选择的区间位于两部分内部直接递归,在两部分之间时,对两边建立凸包,对于每个点只需要找到另一侧的最优点即可,一个点对如果互相不认为对方是优的则必然无用。总复杂度 \(O(n \log n + q)\)。
T3
这种题场上完全不会啊???
大概是说,考虑从第二个栈加入第三个栈的过程是怎么样的。发现第二个栈中如果有相邻两个数 \(x,y\),\(x\) 在上 \(y\) 在下且 \(x+1<y\) 则必然失败,因为如果同时操作中间还有东西,分开操作则会导致 \(x\) 在下 \(y\) 在上。
这个条件显然还是充分条件,容易归纳证明。
现在考虑怎么将第一个栈内的元素加入到第二个栈。
如果每次找到第一个栈中最上方的满足 \(x+1<y\) 的这样一个位置,则 \(x\) 和 \(y\) 必然不可能同时放入第二个栈中,也就是说前缀和后缀是相对独立的。
然后考虑刻画前缀的性质,发现前缀是若干个斜率为 \(+1\) 的线段,并且线段整体逐渐递减,也就是前缀是若干个公差为 \(+1\) 的等差数列。
然后你需要判一些东西。首先是手玩能注意到如果前缀在值域上是不连续的,那么只能整体放到第二个栈。然后有时候你可以把最大值移动到第三个栈并带走第二个栈的一些东西。
如果值域连续,如果 \(A=B=n\),那么肯定是把这些段拼起来在第二个栈中成为一个长度为前缀长度的等差数列,这样你发现加入的数中越靠上越小,这样更能和其他段满足限制。
有 \(A,B\) 限制的时候,你需要分类讨论线段的数量,具体地有 \(=1,=2,>2\) 三种,然后除了数量 \(=2\) 其他的策略都是单一的,数量为 \(2\) 时有一些其他情况,反正整个题就很牛啊!
广东省集 Day5
T1
这个题真难吧???
有一个很牛的转化方法,大概是说对于每条边 \(u \rightarrow v\),如果 \(c_u=0\) 则令 \(u\) 权值加 \(1\),否则 \(u\) 权值减 \(1\),\(v\) 点相反。发现每条 \(0\rightarrow 1\) 边贡献为 \(2\),\(1 \rightarrow 0\) 边贡献为 \(-2\),两端相同则没有贡献。所以记每个点权值为出度减入度,则 \(c_u=0\) 时贡献为其权值,\(c_u=1\) 为相反数。
双方的策略是,对于所有 \(c_u=2\) 按照权值绝对值从大到小选。
然后就有一个背包 DP,逐个将出度与入度 \((x,y)\) 加入,加入顺序按照 \(|x-y|\) 递减加入,就可以维护了。总复杂度 \(O(n^2m^3)\)。
但是你发现还有些问题,比如说怎么考虑 \(c_u = 0/1\) 的点的贡献,但是不难看出这样的点的权值贡献为 \(0\),只对连边方案数有贡献,那么计算答案时只考虑 \(c_u = 2\) 的点构成的集合,然后考虑 \(c_u=2\) 集合内部的入度和出度是多少,剩下的用 \(c_u=0/1\) 的点数计算,这也证明 \(c_u = 0\) 和 \(c_u = 1\) 是等价的。
T2
显然你要做的就是找一个 \(x \geq 2^k\),最小化 \(x+ \sum [a_i > x]\),把他改一下变成最大化 \(\sum [a_i \leq x] - x\),后面这个东西是一个 Hall 定理的形式,也就是每个 \(x\) 向 \(a_i \leq x\) 的 \(a_i\) 连边,求右侧失配点数。
然后你考虑从前往后扫描线并动态维护每个 \([1,r]\) 的最优匹配点集,询问只需要主席树查询一下,\(r\) 增大时必然会在匹配中加入 \(a_r\),然后维护一个线段树判定 Hall 定理即可求答案。
对于 \(x \geq 2^k\) 的限制,将每个点在其 highbit 处计算,这样总复杂度还是 \(O(n \log n)\) 的。
T3
奇异搞笑。
赛时写的乱搞,但是冲过去了,这里不讲。
正解大概是说,考虑二分图带权匹配的求的增广路只有起点和终点可能是未被加入的,其余点都是已经在流量内的了。
然后你直接跑这个最短路,但是需要处理流量内外的权值,这个直接 FWT 做一下就行了。
广东省集 Day6 - 图论选讲 by pb
QOJ10237
一种做法是二分答案 \(mid\),然后判断是否存在两个点 \(u,v\) 使得连接 \(u,v\) 后对于所有 \(dis(x,y)>mid\) 都有 \(\min(dis(x,u)+dis(v,y),dis(x,v)+dis(u,y)) \leq mid\)。
然后你考虑画出这个 \(x,u,v,y\) 的结构,可以发现这两个值不可能同时不超过 \(mid\),否则不加 \(u,v\) 也会有 \(dis(x,y) \leq mid\),然后相当于要对于每个 \(u,v\) 计算 \(dis(x,y)>mid\) 且 \(dis(x,u)+dis(v,y) \leq mid\) 的 \(x,y\) 数量。这个直接枚举 \(x,u,y\) 然后做前缀加即可,总复杂度 \(O(n^3 \log n)\)。
还有一个更优秀的做法,首先要观察到对于 \(x,u,v,y\) 来说,\(x\) 先走到 \(u\) 还是 \(v\) 只取决于 \(dis(u,x)\) 和 \(dis(u,v)\) 的大小关系,必然会先走到 \(dis\) 较小的那个点,这是很显然的,因为如果走到较大的那侧然后跳转到另一侧还不如直接走到另一侧。
然后你考虑对于一个答案 \(mid\) 怎么判定一个 \(u,v\) 是否合法,考虑到 \(x\) 先往哪个方向走是和 \(y\) 无关的,于是假设 \(dis(x,u)<dis(x,v)\),先对于每个 \(x,v\) 算出最大的 \(dis(v,y)\) 使得 \(dis(x,y) > mid\),然后枚举 \(x,u,v\),如果 \(dis(x,u)<dis(x,v)\) 且算出的距离还不够那么 \(u,v\) 不能被选。然后你发现二分答案是不必要的,直接枚举答案动态维护可行的 \((u,v)\) 即可做到 \(O(n^3)\)。
CF1656I
省选结束了你才讲?
大概就是说,形如 K4 和杏仁图无解,手玩容易看出。
然后你考虑每个点双,众所周知点双可以通过开耳分解形式生成,就是初始一个环每次加一条路径,然后你可以发现你加路径不可能加新点,因为加了就是杏仁了,所以整个点双有哈密顿回路,然后非回路上的边是平面图,否则就有 K4 了,于是每个点双是一个有哈密顿回路的平面图,那么你直接广义串并联图求出哈密顿回路,对邻边按顺时针排序就好。不同点双之间没有影响,怎么排都行。
QOJ6807
这题真魔怔。
你考虑把一个长度为 \(10\) 从中间断开成两条长度为 \(5\) 的链,然后你希望对点黑白染色使得两条链的颜色分别是全黑和全白。
然后考虑随机染色,长度为 \(k\) 的环一次染色成功概率为 \(\dfrac{k}{2^k}\),随机 \(1500\) 次可以保证 \(10^{-6}\) 的失败率,为了运行效率可以少随一些。
然后枚举两条断开的边,相当于要求 \(w_{x,y}\) 表示 \(x\) 到 \(y\) 经过同色点的长度为 \(4\) 的路径边权和最大值,这个你直接枚举第一条和最后一条边就容易计算答案。总复杂度 \(O(Cm^2)\),\(C\) 为随机次数。
Xmas Contest 2022 H
这个好难啊。
QOJ7177
首先所有简单环容易用 DFS 生成树上所有非树边对应的树上路径的异或刻画。
然后可以发现对于集合 \(S\),\(S\) 的线性组合构成的所有数的 \(\gcd\) 就等于 \(S\) 内的数的 \(\gcd\),证明显然。
现在我们声称只需要选择一条或两条非树边计算对应的环的权值和,即可线性组合出所有环权值和,即只需要计算选择一条或两条非树边的环权值和的 \(\gcd\) 即可。复杂度 \(O(m^2)\)。
证明大概是说,考虑每条非树边对应了一条树上的链和一条非树边,称这个集合分别为 \(S_1,S_2,\cdots,S_k\),我们要求的是任意选若干个 \(S_i\) 做对称差后得到的集合的权值和的 \(\gcd\)。考虑如果已经求出了 \(w(S_i)\) 和 \(w(S_i \oplus S_j)\),为什么能线性组合出所有对称差集合。发现 \(w(S_i \oplus S_j) = w(S_i + S_j - 2(S_i \cap S_j))\),又 \(w(S_i),w(S_j)\) 已知,所以 \(w(2(S_i \cap S_j))\) 可以被表示。
进一步考虑任意 \(S_{x_1} \oplus S_{x_2} \oplus \cdots \oplus S_{x_k}\),根据 \([x \equiv 1 \pmod 2] = \sum \limits_{i=1}^x \dbinom{x}{i}(-2)^{i-1}\),可以把这个对称差容斥成若干个 \(2^k(S_{a_1} \cap S_{a_2} \cap \cdots \cap S_{a_m})\) 的求和形式,而你考虑这个所谓的 \(S\) 的交集本质是什么,发现非树边一定不存在于交集内,然后容易看出树上若干条路径交所构成的路径必然可以表示为其中两条路径的交,于是证毕。
广东省集 Day7
被打爆了。
T1
不会贪心。
对于这种操作可以考虑序列的差分或者前缀和等,记 \(s_i = \sum \limits_{i=1}^n a_i\)。
考虑操作 \([l,r]\),事实上是选择一个 \(l\),然后 \(s_{l},s_{l+3},\cdots,s_{l+3k}\) 加 \(1\) 或者 \(s_{l},s_{l+3},\cdots,s_{l+3k},s_{l+3k+1},\cdots,s_n\) 加 \(1\),所以有解的充要条件是每个前缀和都非正。
考虑最小化操作次数,发现如果只有类型 \(1\) 的加法,相当于你有一个序列 \(b\),每次选一个区间加 \(1\),目标是所有数为 \(0\),答案显然等于 \(\sum \limits_{i} \max(0,b_{i-1}-b_i)\)。
然后你考虑这个后缀加本质是什么,不妨考虑后缀加操作提前使用,变成选择一个 \(i \in [1,n]\),将 \(s_{i},s_{i+1},\cdots,s_n\) 加 \(1\),然后 \(s_{i - 3},s_{i-6},\cdots,s_{i-3k}\) 加 \(1\)。
你发现这个操作对于序列肯定是不劣的,然后你考虑这种操作会对 \(\sum \max(0,b_{i-1}-b_i)\) 带来什么影响,发现只有 \(s_{i-1}-s_{i+2}\) 与 \(s_{i-2}-s_{i+1}\) 会发生变化,所以每个 \(i\) 有贡献 \(0\) 或 \(1\) 或 \(2\),从前往后先进行贡献为 \(2\) 的,然后进行贡献为 \(1\) 的即可。复杂度线性。
T2
这个题很牛啊。
考虑观察一些性质,比如可以看出一个点往前最短路最长是 \(O(\log n)\) 级别,但是这个东西并不是很能用,场上一直在想这个结果倒闭了。
正确的方向是,你可以发现一个点能到达的点数是 \(O(\sqrt n)\) 量级,原因是考虑这个点到达的编号 \(\leq \sqrt n\) 的点至多 \(\sqrt n\) 个,对于编号大于 \(\sqrt n\) 的点,你发现形态形如一个从起点开始的二叉树,因为 \(a,b\) 随机所以二叉树只有期望 \(O(\log \sqrt n)\) 层,点数期望 \(\sqrt n\),所以能到达的总点数是 \(O(\sqrt n)\) 级别。
考虑设阈值 \(B\),预处理 \(dis(i,j)\),其中 \(1 \leq i,j \leq B\),复杂度 \(O(B \sqrt B)\),查询时从起点广搜,到 \(\leq B\) 的点就终止,与上述分析一样,这是一棵深度期望 \(O(\log \dfrac{n}{B})\) 的树,点数期望 \(O(\dfrac{n}{B})\),于是总复杂度 \(O(\dfrac{n^2}{B} + B\sqrt B)\),取 \(B = n^{\frac{4}{5}}\) 得到最优复杂度 \(O(n^{\frac{6}{5}})\),这样做的话不能 \(O(B^2)\) 空间存储点对距离,需要离线。如果预处理 \(O(B^2)\) 可以得到 \(O(n^{\frac{4}{3}})\),似乎不太能过,但事实上你可以用 short 压缩空间以进一步使用更大的 \(B\),这样已经可以通过了。
T3
这咋会?
广东省集 Day8
T1
这个题做太久了。
题解做法是你把共链的三条边中间那条删掉,然后发现等价于树是菊花,然后可以简单维护。
但我完全没想到这个。
考虑确定了操作次数 \(s\) 怎么求答案,可以二分答案,然后等价于每个点赋一个权值,然后有若干要求某个点子树点权和在一个范围内。这个东西直接 DP 即可,由于多组询问需要把虚树建出来。
对于限制范围 \([l,r]\),大胆猜测 \(s=l\) 或 \(s=l+1\) 或 \(s=r\) 或 \(s=r-1\) 取到最优值,但并不对。观察大样例发现 \(f(s)\) 关于 \(s\) 大概是一段斜率为 \(-1\) 的直线,然后拼上一段为 \(0\) 的低谷,后面的形态不确定,所以直接二分最低点即可。这个复杂度是 \(O(n \log^2 V)\) 的,但是过不去,然后你需要上一些手法,比如 \(s\) 为上述四个值时很大概率都是对的,只需要对很少的询问做二分,这样就对了。
T2
如果删掉的点确定,比较容易求出答案,这个大概是你做一个 DP 状物,然后你只需要线段树合并或者启发式合并之类的,这样当根确定时,你可以求出每个点的子树答案。
然后你考虑求出全局最长 LIS,容易知道删的点必然在链上,于是你从两个链端点分别做一次即可。
复杂度 \(O(n \log n)\) 或 \(O(n \log^2 n)\)。
还有一个做法是,点分治单侧递归,每次向子树 LIS 最大的一侧递归,需要 \(O(\log n)\) 次查询删除单点的结果,复杂度 \(O(n\log^2 n)\) 或 \(O(n \log^3 n)\)。
T3
好题。
首先把每个程序分为若干段,中间用 W 或 Z 隔开,之间全都是加减操作,于是可以合并得到形如 W,\(+x\),Z,\(+x\),Z,W,\(+x\) 等操作,考虑全局变量 \(x\) 是怎么变化的,发现应该是每段程序选择若干个段,然后 \(x\) 应该是所有被选段的权值和,然后你考虑怎样选段符合条件,这等价于所有没被选的段可以在其他段执行时操作,也就是需要存在一个段的排列使得不存在某个程序占用相邻的两段,这个等价于最大值不超过一半。特别地还要求存在某个程序选了前缀与后缀。
对于每个程序求出 \(f_{x,0/1,0/1}\) 表示选了 \(x\) 段,是否选了前缀,是否选了后缀的最小答案,这个问题就是那个经典的选若干个区间最小化总和,根据费用流不难证明凸性,所以分治闵可夫斯基和即可。
考虑原问题,难点在于最大值不超过一半,以及要求某个程序选了前缀,某个程序选了后缀。
先忽略前缀后缀限制,不难想到一个贪心是每个程序都取最小值点,但是这样可能导致最大值超过一半,此时需要选择一些程序将值左右移动。不难证明最终必然会存在某个程序的段数恰好等于一半。
于是将情况分为两类,分别是每个都取最小值,以及存在某个等于一半。
先考虑每个都取最小值的情况,可以发现一个程序选了前缀或后缀,对最小值位置的改变量为 \(O(1)\)。于是你可以 DP,状态记录目前段数的最大值与和,对于每个 \(i\) 状态数显然是 \(O(1)\) 的,所以总复杂度是线性的。
对于某个等于一半的情况,类似上面的分析,可以发现等于一半的这个位置应该是不考虑前缀后缀条件下最优段数总和前 \(O(1)\) 大的,枚举这个之后对别的做分治分治闵可夫斯基和即可。复杂度 \(O(\sum l_i \log \sum l_i)\)。
广东省集 Day10
T1
显然硬币相互独立,所以只需要算出每个点的 SG 值。
由于不能往上移动,考虑从下到上处理 SG 值。
可以发现对于某一行,如果存在障碍物,那么是容易计算答案的。只需要设状态 \(f_{i,j,0/1/2}\) 表示在 \((i,j)\),只能向左 / 右 / 无限制走的 SG 值,由于存在障碍物所以不可能走到之前走过的位置。
对于没有障碍物的某一行,暴力做是枚举 \(j\),然后算前后缀 SG,容易发现前后缀操作中每一步的 SG 值都不超过 \(2\),于是直接对前后缀做预处理即可做到总复杂度 \(O(nm)\)。
T2
看似只需要计算 \(O(1)\) 个起点对应的终点结果,但是发现操作 \(2,4\) 不会交换第一行 / 列和最后的行 / 列,所以不是很能直接这么做。
考虑把 \(n \times m\) 的网格不断镜像翻转铺满整个平面,按照题面黑白染色,发现此时操作 \(2,4\) 可以视为第一行 / 列和上一行 / 列交换,这是因为最上面的一行和更上面的一行是完全相同的,最后一行 / 列同理,然后你只需要计算 \(O(1)\) 个起点的终点了。
T3
又被 trick 击杀了。
这个东西的直接想法应该是行列拆点建立二分图,每个棋子 \((i,j)\) 连接左侧第 \(i\) 个点和右侧第 \(j\) 个点。然后一个网格图合法当且仅当选出边两两匹配方式唯一,两条边能在匹配中当且仅当其共用某个端点。
考虑什么情况下存在唯一的匹配方式。
对每个连通块单独考虑,若其为一棵树,随便选定一个根,从叶子向上合并,容易证明存在合法的匹配方式等价于边的数量为偶数,对于要求匹配唯一,考虑合并的过程是,对于每个点 \(u\) 考虑其所有儿子,若儿子边数为偶数,两两匹配,否则和父亲的边一起匹配,所以要求每一步都满足仍存在的儿子数量不超过 \(2\)。
容易看出如果一个连通块有环则匹配方案必然不唯一,这是因为你可以钦定环上某条边不和其中一端的其他边匹配,也就是把这条边分别拆成新点并给予两侧点,剩下的树要么无解要么有解,由于选的边至少能对应两种树且这条边对应的匹配必然不同所以方案必然不唯一。
现在相当于你得到了若干棵树,你要在树上加一些边使得整个森林的每棵树都有唯一解。
容易发现整个过程应该是,先用孤点向一些点加边,然后每次选出一棵合法的树向某棵不合法的树加边。这个加边必然能成功原因是图是二分图所以除了孤点的每棵树上同时存在两种颜色的点。
考虑左侧点总共需要连 \(c_0\) 条边,右侧点总共需要连 \(c_1\) 条边,总共有 \(k\) 棵树,\(x_0\) 个左侧孤点和 \(x_1\) 个右侧孤点,则有解当且仅当 \(\max(0,c_0-x_1) + \max(0,c_1-x_0) < k\),必要性显然,原因是将所有孤立点加边后还需要至少 \(\max(0,c_0-x_1)+\max(0,c_1-x_0)\) 条边,而总共 \(k\) 棵树至多贡献 \(k-1\) 条边,所以左侧严格小于右侧。充分性可以反证,若存在某时刻所有不合法的树所需的边都大于合法的树的数量,则设合法树有 \(a\) 个,不合法树有 \(b\) 个,则需要边数至少为 \(b(a+1)\)。\(b(a+1) \geq a+b\) 显然成立,故矛盾。
于是考虑求出所有可能的 \((c_0,c_1)\) 并计算 \(c_0+c_1\) 的最小值。由于条件的限制就应该满足 \(c_0,c_1\) 尽可能小,所以考虑每棵树分别 DP,记 \(f_{i,j,k}\) 表示 \(i\) 的子树中,\(c_0=j\),点 \(i\) 的除了父亲的有效儿子数量为 \(k \in [0,2]\) 时的最小 \(c_1\),转移同树形背包。由于 \(j \leq sz_i\),所以总复杂度 \(O((n+m)^2)\)。

浙公网安备 33010602011771号