2024.3 做题记录
222. CF1936D Bitwise Paradox
和 CF1004F Sonya and Bitwise OR 很像。
考虑一次询问怎么做。考虑分治,每次只计算左端点在 \([l, mid]\),右端点在 \([mid + 1, r]\) 的区间的贡献。对于每个 \(i \in [l, mid]\),维护最小的 \(j \in [mid + 1, r]\) 使得 \([i, j]\) 的或 \(\ge v\),那么 \(\max\limits_{k = i}^j a_k\) 对答案有贡献。
考虑带修怎么做。考虑套上线段树,利用线段树的分治结构,问题变成了如何合并两个区间的答案。
按位或有个很好的性质,就是前(或后)缀的或只会变化 \(O(\log V)\) 次。所以我们对于线段树上每个结点,维护前缀和后缀的或第一次变化的位置。
计算左端点在左结点,右端点在右结点的区间贡献,就枚举左结点所有后缀或第一次变化的位置作为左端点,双指针维护使得区间或 \(\ge v\) 的最靠左的右端点即可。
注意到 \(a\) 不变,可以使用 ST 表单次 \(O(1)\) 计算 \(a\) 的区间最大值。合并两个区间的复杂度为 \(O(\log V)\)。所以总时间复杂度为 \(O((n + q) \log n \log V)\)。
223. CF1540D Inverse Inversions
小清新题。
首先容易发现每个合法的 \(b\) 唯一对应一个排列,大概就是每个时刻排列元素的相对顺序,然后插入到相应的位置。
但是这样太麻烦了。发现题目只要求求单点的 \(p\) 值。这应该有更简单的方法。
考虑令 \(b_i \gets i - b_i\) 表示 \(p_i\) 在前缀 \([1, i]\) 的排名。那么我们时刻维护 \(p_i\),然后遍历 \(i + 1\) 到 \(n\),若 \(b_i \le p\) 那么令 \(p \gets p + 1\)。这样我们得到了一个 \(O(nq)\) 的做法。
一种优化方向是分块。预处理出每个块每个数经过后会变成什么。设 \(x\) 经过后变成 \(f_x\)。容易发现 \(f\) 的值域为 \([1, len]\),也就是说它是一个 \(1 \sim len\) 的分段函数。那么求出每一段的断点就可以二分求出一个数经过这个块后会增加多少。
考虑如何对一个块预处理 \(f_x\)。相当于每次找到第一个 \(a_i + i \ge k\) 的位置 \(i\),然后对 \([i, n]\) 加 \(1\)。容易树状数组维护,找到第一个位置可以树状数组上二分。
这样全部找到的位置就是分段函数的断点。
时间复杂度 \(O(n \sqrt{n} \log n)\)。
224. P2791 幼儿园篮球题
一般推式子题。
考虑答案即为:
即枚举抽到没气的球的个数。
我们希望把 \(i^L\) 拆出来,这样剩下的部分是一个类似范德蒙德卷积的形式。那么利用 \(x^n = \sum\limits_{i = 0}^n {n \brace i} \frac{x!}{(x - i)!}\) 可以拆 \(i^L\),然后变化枚举顺序,约分,就可以使用范德蒙德卷积。最后答案是:
容易 \(O(N)\) 预处理出阶乘及其逆元,\(O(L \log L)\) NTT 预处理出 \(L \brace i\)。然后就做完了。
225. CF1930G Prefix Max Set Counting
小清新题。题外话,感觉和联考的一道题很像。
直接考虑 dp,设 \(f_u\) 表示当前前缀 \(\max\) 是 \(u\) 的方案数。
考虑哪些点可以转移到 \(u\)。显然 \(1 \to fa_u\) 路径上的 \(\max\) 可以转移,除了这个点其他的祖先都不能转移。
考虑非祖先的情况,设 \(w = \text{lca}(u, v)\),若 \(v\) 是 \(w\) 下一层儿子的子树的 \(\max\) 且 \(v < u\) 且 \(v\) 大于 \(1 \to fa_u\) 路径上的 \(\max\) 也可以转移,相当于遍历完这棵子树就遍历 \(u\) 所在子树。
可以使用树状数组动态维护区间 dp 值和,转移顺序是把儿子按照子树 \(\max\) 升序排序后依次 dfs。时间复杂度 \(O(n \log n)\)。
226. P7247 教材运送
唉,没想到直接设 \(n\) 元方程。
套路 min-max 容斥:
设 \(f_T(u)\) 为当前 \(s = u\),走到 \(T\) 中的点的期望代价。
有:
其中 \(d_{u, v}\) 为 \(u \to v\) 的代价。
那么我们可以列出这样的 \(n\) 条方程。直接高斯消元解是不现实的。设 \(g_u = \sum\limits_{v = 1}^n d_{u, v}\)。不妨把这 \(n\) 条方程相加。设 \(m = |T|, s = \sum\limits_{i = 1}^n f_T(i) = \sum\limits_{i \in T} f_T(i)\),有:
那么 \(f_T(1) = s + g_1 = \frac{\sum\limits_{i \notin T} g_i}{m} + g_1\)。
那么:
至此,只需预处理出来 \(\sum\limits_{i = 1}^n g_i\) 和 \(g_1\) 即可快速计算。容易 \(O(n)\) 预处理。所以总时间复杂度为 \(O(n)\)。
227. CF1372F Omkar and Modes
直接考虑分治,设要确定 \([l, r]\) 的答案。问一遍区间众数 \(p\),出现次数为 \(x\)。若我们确定了一个位置 \(a_i = p\),注意到 \([i - x + 1, i]\) 和 \([i, i + x - 1]\) 中至少有一个区间最小众数是 \(p\),从而可以确定 \(p\) 的出现位置范围,然后再递归下去。
找到 \(a_i = p\),可以从 \(l\) 开始隔 \(x\) 问一个单点。
记忆化之后总询问数不超过 \(4k\)。
228. CF1515F Phoenix and Earthquake
发现对于任意一棵树,若 \(\sum a_i \ge (n - 1) x\) 就有解。
考虑归纳。随便取一个叶子 \(u\)。
若 \(a_u + a_{fa_u} \ge x\),那么直接把 \(u\) 和父边删掉,把 \(a_{fa_u}\) 变为 \(a_{fa_u} + a_u - x\)。
否则这条边最后一定能删掉。考虑剩下的部分即可。
构造就取一棵生成树,按照上面递归做即可。
229. CF1687E Become Big For Me
考虑如何表示 \(\gcd\limits_{i \ne j} a_i a_j\),把每个数分解质因子,这个质因子贡献的次数是,对于每个质因子,次数前 \(2\) 小的次数的和。
我们现在希望用一些 \(\text{lcm}\) 去表示这个东西。考虑(扩展)min-max 容斥用到质因子的次数上,那么:
但是显然不能直接做 \(O(n 2^n)\) 次操作。考虑取出一个长度不超过 \(14\) 的子集,使得它的 \(\gcd\limits_{i \ne j} a_i a_j\) 与原序列的相等。
那么我们只要做两次这样的操作即可:取出一个 \(\gcd\limits_{i = 1}^n a_i\) 与原序列相等的子集。
取出这个东西可以先随便选一个数 \(x\),考虑它含有的质因子,把整个序列这个质因子次数最少的数加入集合。最后如果集合大小 \(= 8\) 那么一定可以去除一个使得 \(\gcd\) 不变。
230. CF917C Pollywog
套路题。
设 \(f_{i, S}\) 为当前考虑到第 \(i\) 位,接下来 \(k\) 个石头是否被占用的状态是 \(S\)。转移容易根据 \(q\) 个特殊石头分段然后矩阵快速幂优化。
可以把 dp 数组看成一个向量,预处理出转移矩阵的 \(2^i\) 次幂,然后直接向量乘矩阵。
直接做状态数是 \(2^k\),已经可以通过。注意到只有 \(|S| = x\) 的状态才有用,所以状态数可以优化到 \(\binom{k}{x}\)。
231. P10218 [省选联考 2024] 魔法手杖
折戟沉沙了。
考虑直接在 01Trie 上贪心。自顶向下地考虑。
首先判断能否把 \(ans\) 这一位设成 \(1\)。要么把 \(0\) 子树全部加强并且 \(x\) 这位取 \(0\),要么把 \(1\) 子树全部加强并且 \(x\) 这位取 \(1\)。我们只在可能更新答案的时候递归下去。
只有 \(ans\) 不可能设成 \(1\) 才把 \(ans\) 设成 \(0\),然后再递归下去。
若递归下去没有使得 \(ans\) 之前那一位为 \(1\),也不需要考虑直接把 \(ans\) 那一位设成 \(0\) 了,因为根据 \(x \oplus y \le x + y\) 所以一定不优。
232. CF1687D Cute number
考虑直接把好数看成一段一段的,枚举 \(a_1\) 所在段。因为段长大概是单增的所以可以直接二分最右的必须在同一段的数。维护一下当前 \(k\) 的范围 \([L, R]\)。然后再考虑剩下的数。当发现 \(L > R\) 时立刻退出。
复杂度看上去很对,它过了。
233. CF1935F Andrey's Tree
赛后 15min 过题/ll。
删掉点 \(u\) 后树会分成若干棵子树。给每个子树一个编号,令 \(c_i\) 表示 \(i\) 所在子树的编号。然后题目要求一个类似最小生成树的东西。
既然要求最小生成树,那肯定先从 \(|a - b| = 1\) 选起。对于所有 \(i \in [1, u - 2] \cup [u + 1, n]\),连边 \((c_i, c_{i + 1})\),那么新图上最多有两个连通块。
新图只有一个连通块就直接做完了,否则 \((c_{u - 1}, c_{u + 1})\) 一定不在同一个连通块,合并它们的代价是 \(2\)。这样就是最优策略。
考虑怎么快速找到全部有用的 \((c_i, c_{i + 1})\) 的边。对于一对 \((i, i + 1)\),设 \(x = \text{lca}(i, i + 1)\)。发现只有当 \(u = x\) 时 \(i, i + 1\) 才都在 \(x\) 的子树中且在 \(x\) 的不同儿子的子树。设 \(u\) 的一个儿子 \(y\) 为 \(i\) 所在子树,那么 \(fa_i \to y\) 路径上的所有点满足 \(i\) 在它的一个儿子的子树,\(i + 1\) 在它父亲的子树。反过来对于 \(i + 1\) 也类似。
当 \(u = x\) 时可以用 vector
存全部满足的 \(i\);否则维护每个点 \(v\) 的子树中的使得 \(dep_z\) 最小的 \(i\)(这样就能尽可能使得 \(i + 1\) 在 \(v\) 父亲那棵子树)。用可撤销并查集维护连通块的合并。
总时间复杂度 \(O(n \log n)\)。
234. CF868E Policeman and a Tree
考虑直接 dp,设 \(f_{u, v, k, x}\) 表示当前走 \(u \to v\) 的边,还剩下 \(k\) 个罪犯,\(v\) 子树内有 \(x\) 个罪犯。
转移考虑 \(v\) 的儿子的罪犯分布。罪犯要找到一种数量分配使得分出来之后 dp 值最小值最大。这部分用背包。
dp 因为顺序难以确定所以可以考虑记搜实现。
时间复杂度 \(O(n^2 m^3)\)。
235. P10239 [yLCPC2024] G. 系ぎて
枚举最小和次小的数计算即可。要讨论是否相等。
236. CF818G Four Melodies
经典费用流模型。拆点,对于一对 \(i, j\),若 \(j\) 可以接在 \(i\) 后面就连流量 \(1\),费用 \(0\) 的边。一个点的入点和出点连流量 \(1\),费用 \(1\) 的边。跑最大费用最大流即可。
优化建图是容易的,前缀优化建图即可。
时间复杂度 \(O(n^2)\)。
237. CF321D Ciel and Flipboard
设 \(f_{i, j}\) 为 \((i, j)\) 是否变为相反数。
那么对于一行有性质:\(f_{i, m} \oplus f_{i, j} = f_{i, m + j}\)。列一样。
所以只要知道 \(f_{1 \sim m, m}\),就能知道 \(f_{m + 1 \sim n, m}\)。然后发现每个 \(f_{m, i}\) 的决策是相互独立的,确定了 \(f_{m, i}\),每个 \(f_{i, j}, i < m, j < m\) 的决策又是相互独立的。
所以直接枚举 \(f_{1 \sim m, m}\),然后嵌套取最大值即可。时间复杂度 \(O(2^m \text{poly}(n))\)。
238. CF1876G Clubstep
喵喵提。
暴力显然是贪心直接从右往左操作。相当于是维护一个答案 \(ans\),\(i\) 从 \(r\) 往 \(l\) 遍历,让 \(ans \gets ans + i \left\lceil\frac{x - a_i}{2}\right\rceil\),然后 \(x \gets \left\lfloor\frac{x + a_i}{2}\right\rfloor\)。
考虑离线,从右往左扫,维护每个点有多少个 \((x, d)\)(\(d\) 为询问编号)。感受一下 \(x\) 不同的这样的对不是很多。定义势能为 \(\sum\limits_{i = 1}^{m - 1} \log(x_{i + 1} - x_i)\),每次操作势能会减去 \(m\),加入新数,势能会加上 \(\log V\)。
可以用带权并查集维护一个询问被挂在了哪个询问上(若经过某次操作后两次询问的 \(x\) 相同就不用考虑了)。
239. CF1854D Michael and Hotel
考虑若求出所有 \(1\) 所在环上的点,就可以看每个点跳 \(n\) 步后是否在 \(1\) 所在环上,就能找到连通块的所有点。
不妨先求出 \(k\) 个在环上的点 \(S\),然后看是否能倍增,即 \(k\) 能否扩展到 \(2k\)。
注意到每个点询问跳 \(k\) 次能否跳到这些点即可。这样相当于求出这 \(k\) 个点后移 \(k\) 个位置后的另外 \(k\) 个点。
注意除了这 \(k\) 个点还可能求出别的点(因为这 \(k\) 个点挂的子树里面可能有跳 \(k\) 步到环上点的)。但是注意到把它们都加进 \(S\) 显然不影响正确性,因为我们的目标仅仅是求出 \(1\) 所在连通块的所有点。
240. P6846 [CEOI2019] Amusement Park
可以直接对数量做 dp,但是应该过不了。
观察到若翻转边集 \(S\) 合法,那么边集 \([1, m] \setminus S\) 也一定合法。
所以只要计数 DAG 然后乘 \(\frac{m}{2}\) 即可。
计数 DAG 是经典问题。设 \(f_S\) 为集合 \(S\) 的点形成 DAG 的方案数。转移考虑钦定入度为 \(0\) 的集合 \(T\),\(T\) 要满足内部点两两无边,然后乘上容斥系数 \((-1)^{|T| - 1}\)。
241. P10221 [省选联考 2024] 重塑时光
唉,现在发现是套路题。
只考虑非空序列,系数是容易计算的,并且只和分的段数有关。
考虑合法当且仅当缩点后是 DAG 并且每个集合的序列是内部 DAG 的拓扑序。
设 \(h_S\) 为点集 \(S\) 拓扑序个数,容易 \(O(n 2^n)\) 预处理。
设 \(g_{S, i}\) 为点集 \(S\) 分成 \(i\) 个互不连边的集合方案数。容易 \(O(n 3^n)\) 预处理。
设 \(f_{S, i}\) 为点集 \(S\) 分成 \(i\) 个集合,且缩点后图是 DAG 的方案数。转移是经典容斥,枚举 \(j\) 个大点入度为 \(0\),容斥系数为 \((-1)^{j + 1}\)。这部分是 \(O(n^2 3^n)\) 的,过不去。
发现 \(f_{S, \ast}\) 的转移是卷积形式。考虑直接转成点值,最后拉插得到每一项的系数即可。复杂度降为 \(O(n 3^n)\)。
242. CF1874E Jellyfish and Hack
显然 \(\text{fun}(P)_{\max} = \frac{|P|(|P| + 1)}{2}\)。
考虑大力 dp,设 \(f_{i, j, k}\) 为 \(|P| = i\),\(P_1 = j\),\(\text{fun}(P) = k\) 的排列 \(P\) 的个数。此时 \(|L| = j - 1, |R| = i - j\)。转移枚举 \(L_1, R_1, \text{fun}(L), \text{fun}(R)\),有:
答案即 \(\sum\limits_{i = 1}^n \sum\limits_{j = m}^{\frac{n(n + 1)}{2}} f_{n, i, j}\)。
\(\binom{i - 1}{j - 1}\) 的系数是已知 \(L, R\) 内元素的相对大小关系,它们组成 \(P_{2 \sim n}\) 的方案数。
发现转移最后一维出现了类似卷积的形式,考虑用多项式刻画转移。即设 \(F_{i, j}(x) = \sum\limits_{k} f_{i, j, k} x^k\)。那么:
令 \(G_i(x) = \sum\limits_{j = 1}^i F_{i, j}(x)\),那么:
因为 \(\deg G_n(x) \le \frac{n(n + 1)}{2}\),所以求出 \(G_n(x)\) 的 \(\frac{n(n + 1)}{2} + 1\) 个点的点值,就能拉插推得 \(G_n(x)\) 每一项的系数。
考虑如何点值转系数:
枚举 \(i\),那么 \(\prod\limits_{j \ne i} \frac{1}{x_i - x_j}\) 是可以预处理阶乘及其逆元后 \(O(1)\) 算的(因为 \(x_i = i\))。\(y_i\) 可以朴素 \(O(n^2)\) 计算。
考虑如何算 \(\prod\limits_{j \ne i} (x - x_j)\)。先算出 \(H(x) = \prod\limits_{i = 1}^n (x - x_i)\),然后那个东西相当于 \(\frac{H(x)}{x - x_i}\)。做大除法即可。
时间复杂度 \(O(n^4)\)。虽然枚举带了个 \(\frac{1}{4}\) 常数但是需要不停取模所以跑得很慢。
243. P10175 「OICon-02」Subtree Value
拆乘积,\(a_u + |S| = (x_1 + x_2) U + y_1 + y_2\),其中 \(a_u = x_1 U + y_1, |S| = x_2 U + y_2\)。
可以先枚举 \(y_2\)。容易发现 \(x_2\) 只能选 \(V\) 次。然后再做背包即可。设 \(f_{u, i, j}\) 为,以 \(u\) 子树为根的连通块有 \(i\) 个点,选了 \(j\) 次 \(x_2\) 的乘积之和。
时间复杂度 \(O(n^2 U V^2)\)。
244. [AGC022E] Median Replace
考虑对于一个确定的串怎么判断合法性。
容易发现删到某个时刻若 \(1\) 的个数大于 \(0\) 的个数了,因为我们肯定不会蠢到在不是全 \(1\) 的时候删 \(111\),所以 \(c_1 - c_0\) 在不是全 \(1\) 的时候至少是不会变小的。
所以我们的目标就是让 \(c_1 - c_0\) 尽可能大。
发现删 \(000\) 这个操作看起来很优,它能使 \(c_1 - c_0\) 增加 \(2\)。所以我们只要贪心地删 \(000\) 就可以了……吗?
考虑这个串:\(0010011\),删不了 \(000\),并且 \(c_1 - c_0 < 0\)。但是实际上这个串可以先删中间的 \(010\) 变成 \(00011\),再删 \(000\)。发现问题出在没有删 \(010\)。发现删 \(010\) 之后 \(c_1 - c_0\) 不变,并且它左侧和右侧的 \(0\) 可以拼在一起形成一个新的 \(000\)。感性理解一下这个策略是不劣的。
也就是说有 \(000\) 或者 \(010\) 就删。最后判 \(c_1 - c_0\) 是否 \(> 0\) 即可。
考虑计数。可以考虑设计一个自动机,并且记录当前考虑到的前缀的 \(c_1 - c_0\) 的值。我们有:
注意这里 \(1\) 可以变成 \(\varnothing\) 是因为这个 \(1\) 之后不会参与删除了,所以直接忽略它,并且让 \(c_1 - c_0\) 增加 \(1\)。
还有:
所以自动机状态数为 \(5\)。先把当前在自动机上的结点记入状态。还要记一个当前 \(c_1 - c_0\) 的值。
发现若 \(c_1 - c_0 \ge 3\) 那么把后面的全部删了之后一定满足 \(c_1 - c_0 > 0\)。同时由于我们的策略,不会出现 \(c_1 - c_0 \le -3\) 的情况。所以 \(c_1 - c_0 \in [-2, 2]\),这样就可以记入状态了。
时间复杂度 \(O(n)\)。
245. P8987 [北大集训 2021] 简单数据结构
考虑若原来的序列是不降的,那么进行 \(1\) 操作或 \(2\) 操作序列仍然不降。那么 \(1\) 操作直接线段树上二分然后打覆盖标记,\(2\) 操作直接打标记即可。
考虑一般情况,发现某个时刻所有被 \(1\) 操作影响过的 \(i\)(存在一次 \(1\) 操作使得 \(a_i \ge v\))组成的集合 \(S\),\(S\) 内部的序列是单调的。
于是整个序列被分成了两部分:\(S\) 和 \([1, n] \setminus S\)。对于 \(S\),\(1\) 操作直接线段树上二分然后打标记。\(2\) 操作就分别对两个部分打个标记即可。
线段树一个结点需要维护:\(S\) 部分的最大值及其最大下标(为了 \(2\) 操作后计算新的最大值),两部分分别的和及其下标的和,\(S\) 部分的元素个数和这个区间在 \(S\) 部分的最大下标(打覆盖标记时需要将最大值的最大下标重置为这个值)。
剩下最后一个问题:如何计算一个元素何时加入 \(S\)。考虑二分 \(mid\),相当于查询是否 \(\exists j \in [1, mid], b_j \times i + a_i \ge v_j\)(其中 \(b_i\) 为第 \(i\) 次 \(1\) 操作前面的 \(2\) 操作次数)。变形得 \(\min\limits_{j = 1}^{mid} \{ -b_j \times i + v_j \} \le a_i\)。考虑整体二分,维护一个 \((b_j, v_j)\) 的下凸包,check 就维护一个凸包上的指针即可。因为 \(b_j\) 单调,所以不用排序。注意可能存在若干个 \(b_j\) 相等,这种取它们 \(v_j\) 的最小值即可。
总时间复杂度 \(O(n \log n)\)。
246. CF1437F Emotional Fishermen
考虑若确定了前缀最大值元素,那么把非前缀最大值元素从大到小排序,那么第 \(i\) 个元素有 \(cnt + i - 1\) 种插入方式,其中 \(cnt\) 为大于等于第 \(i\) 个元素两倍的前缀最大值元素个数。
发现这个值就等于 \(i - 1 - [2a_i > a_j]\),其中 \(i\) 是在原序列的顺序,\(j\) 是上一个前缀最大值。
然后直接 dp 就行了,设 \(f_{i, j}\) 为从大到小的前 \(i\) 个元素,上一个前缀最大值为 \(a_j\) 的方案数。转移容易。时间复杂度 \(O(n^2)\)。
247. [ARC171C] Swap on Tree
神秘的。为啥我觉得 C >>>>>> D 啊!
结论:两种方案产生的 \(a\) 不同,当且仅当,每个点引出的交换过的边,相对的交换顺序相同。
所以对于一个确定的边集 \(E\),设 \(f_u\) 为 \(u\) 和几个点相连,那么答案为 \(\prod f_u!\)。
据此每个点做一个背包即可。
248. CF924F Minimal Subset Difference
考虑如何求 \(f(n)\)。发现只能背包,但是背包的上界可以只开到 \(90\)。
直接把背包每一位的值记在 dp 状态里面肯定不行。但是可以猜测用到的背包状态不会很多。
弄一个自动机出来,发现位数 \(\le 18\) 的时候自动机结点数量 \(< 2 \times 10^4\)。
然后预处理 \(f_{i, j, u}\) 表示还要填 \(j\) 位,答案上界为 \(i\),当前在自动机上的结点 \(u\) 的方案数。
然后算 \(1 \sim n\) 的答案,枚举在哪一位开始不顶上界即可。
跑得很快。
249. CF618F Double Knapsack
怎么想到的!!!
直接强化成选子段。考虑求前缀和,相当于求出一组 \((i, j, k, l)\) 使得 \(b_k - a_i = b_l - a_j\)。
不妨假设 \(a_n \le b_n\)。对于每个 \(i\) 求出最小的 \(j\) 使得 \(b_j \ge a_i\)(这部分可以双指针),那么 \(b_j - a_i \in [0, n - 1]\)。又因为有 \(n + 1\) 对这样的 \((i, j)\)(\(i \in [0, n]\)),所以根据抽屉原理一定至少有一组的 \(b_j - a_i\) 相同。
250. CF1218G Alpha planetary system
设 \(w_u\) 为点 \(u\) 的权值 \(\bmod 3\) 的值,\(c_u\) 为 \(u\) 所属的组。有个想法就是让 \(w_u = c_u\),这样条件一定满足。
考虑如果能做树,那么直接把非树边权值设为 \(3\) 就能做一般图。
树就一定能使非根结点的 \(w_u = c_u\)。重点在根结点。发现我们可以选择一个包含根结点的奇环来改变 \(w_u\) 而不影响其他点的 \(w\) 值,就是类似 \(+2, +1, +2\) 交替进行即可。
如果没有奇环,那么图是一个二分图。我们仍然使非根结点的 \(w_u = c_u\)。不妨假设根结点的 \(c_u = 1\)。
发现若 \(w_{rt} = 2 \land deg_{rt} > 1\) 才不满足。此时找到两条边 \((rt, u), (rt, v)\),把它们权值 \(+1\),这样 \(w_{rt}\) 变为 \(1\),\(w_u, w_v\) 均变为 \(0\),满足条件。
感觉想到对树和二分图分别构造还是有点难度的?
251. P10066 [CCO2023] Binaria
对于相邻两个的连续段的和可以推出 \(a_i\) 和 \(a_{i + m}\) 的关系。要么相等,要么 \(a_i = 1, a_{i + m} = 0\),要么 \(a_i = 0, a_{i + m} = 1\)。
所以最后只用对 \([1, m]\) 考虑。可以用并查集维护相等关系,答案就类似还剩下多少个位置,在这些位置中选若干个变成 \(1\) 的一个组合数。
252. CF1552H Guess the Perimeter
这个题智慧的很啊!!!
考虑先问出面积。设矩形的底为 \(a\),高为 \(b\)。考虑若问 \(d \mid x\) 的一些点,设答案为 \(f(d)\),那么一个很显然的性质是 \(f(1) = d f(d)\) 成立当且仅当 \(d \mid b\)。
尝试用二的次方搞点事情。设能整除 \(b\) 的最大二的次方为 \(p\),那么我们有 \(a = |2 f(2p) - \frac{f(1)}{p}|\)。关键就是 \(p \to 2p\) 只会对在矩形中的列造成 \(\pm 1\) 的影响。
所以直接二分找到最大的 \(p\) 即可。问一次面积 \(1\) 次询问,二分 \(3\) 次询问。
253. 2024.3.16 模拟赛 T2 树状数组(fenwick)
把下标补齐到 \(2^k\),然后区间更新就直接打标记。
没见过这个 trick 啊。
254. [ABC345F] Many Lamps
首先 \(K\) 为奇数时无解。
然后图的每个连通块显然互相独立,分别考虑。
每个连通块随便求一棵生成树,自底向上操作。如果当前的 \(K\) 有剩余,为了钦定 \(u\) 是亮的,可能需要翻转 \(u \to fa_u\) 的边。
这样操作一遍如果最后根不是亮的,说明连通块大小为奇数,我们显然只能做到让偶数盏灯亮,所以不用管它。
最后做完每个连通块后若 \(K\) 还有剩余就无解。
求生成树我偷懒用了并查集,所以复杂度带个 \(\log\)。
255. CF1943C Tree Compass
发现对于一条链,一次操作最多能染黑这条链上的 \(2\) 个点。
所以我们把直径拎出来,设直径长度为 \(d\)。
考虑一条长度为 \(d\) 的链至少要多少次能全染黑。
- 若 \(d\) 为奇数,显然从直径中点 \(u\) 开始做 \((u, 0), (u, 1), \ldots, (u, \frac{d - 1}{2})\) 即可。这样操作次数已经顶到下界了,而且发现由直径的性质,这样能把整棵树都全部染黑。
- 若 \(d\) 为偶数,发现 \(d = 2\) 和 \(d = 4\) 时都需要 \(2\) 次。考虑若 \(d \bmod 4 = 0\),可以找到直径的中心边 \((x, y)\),依次做 \((x, 1), (y, 1), (x, 3), (y, 3), \ldots, (x, \frac{d}{2} - 1), (y, \frac{d}{2} - 1)\) 即可,只需 \(\frac{d}{2}\) 次操作。若 \(d \bmod 4 = 2\),只能做 \((x, 0), (x, 1), \ldots, (x, \frac{d}{2})\),需要 \(\frac{d}{2} + 1\) 次操作。
找直径即可。时间复杂度 \(O(n)\),开 \(2 \times 10^3\) 是因为 checker 要 \(O(n^2)\)。
256. CF1943D2 Counting Is Fun (Hard Version)
被自己的赛时智障操作气笑了。谁告诉你容斥钦定了几个要记到状态里面的。。。/tuu
显然先找“好数组”的充要条件。对原数组 \(a\) 差分,设 \(b_i = a_i - a_{i - 1}\)。那么一次可以选择一对 \((i, j)\) 满足 \(i \le j - 2\),然后给 \(b_i\) 减 \(1\),给 \(b_j\) 加 \(1\)。
我们从左往右操作。注意到我们不能操作相邻的一对元素,所以若某个时刻 \(b_i > 0\) 且 \(b_{1 \sim i - 2}\) 都为 \(0\) 就不合法。这就是充要条件。
充要条件可以表述成 \(b_i + \sum\limits_{j = 1}^{i - 2} b_j \ge 0\),即 \(a_i - a_{i - 1} + a_{i - 2} \ge 0\),注意 \(a_0 = a_{n + 1} = 0\)。
对于 \(n \le 400\) 可以直接做一个 \(O(n^3)\) dp,设 \(f_{i, j, k}\) 为考虑了 \([1, i]\) 的前缀,\(a_{i - 1} = j, a_i = k\) 的方案数。因为合法的 \(a_{i - 2}\) 是一段后缀,所以预处理后缀和即可做到 \(O(1)\) 转移。这样可以通过 D1。
对于 \(n \le 3000\) 显然不能这么做了。发现 dp 状态数都成瓶颈了,换个思路,考虑容斥,钦定一些位置 \(i\) 是满足 \(a_i > a_{i - 1} + a_{i + 1}\)(显然这些位置不会相邻),容斥系数就是 \(-1\) 的位置个数次方。
对于 \(i\) 被钦定的方案,注意到我们不用枚举 \(a_i\),只要知道 \(a_{i - 1}\) 和 \(a_{i + 1}\),就能算出 \(a_i\) 的取值个数为 \(m - a_{i - 1} - a_{i + 1}\)(令题面中的 \(k\) 为 \(m\))。
所以设 \(f_{i, j}\) 为考虑了 \([1, i]\) 的前缀,\(a_i = j\),每种方案乘上容斥系数的和。那么有 \(f_{i, j} = \sum\limits_{k = 0}^m f_{i - 1, k} - (m - j - k) f_{i - 2, k}\),容易前缀和优化。
时间复杂度 \(O(n^2)\)。
257. QOJ8165 Numerous Elimination
给一个状态设一个势能函数为 \(\sum\limits_{i = 1}^n f(a_i)\)。终态即 \(a_i = i - 1\)。
\(f\) 需要满足 \(2 f(x) + 1 = f(x + 1) + f(0)\)。钦定 \(f(0) = 0\),那么 \(f(x) = 2^x - 1\)。所以答案即为 \(2^n - n - 1\)。
258. CF1037G A Game on Strings
显然转化成计算一段区间的 SG 值。
注意到有用的区间只有,对于一个字母的相邻两个出现位置组成的区间的所有前缀和后缀和整段,个数是 \(O(n |\Sigma|)\) 的。
对于整段的 SG 值,按长度排序后把它们当成询问然后记搜,最后对这个做前缀和即可。
询问可以直接记搜,注意到我们已经预处理过整段的 SG 值所以直接使用就行了,只有边角的前缀和后缀需要递归下去。
259. CF264D Colorful Stones
找到每行最先到的列和最后到的列,减掉中间没有前驱的点即可。
\((i, j)\) 没有前驱相当于 \(s_i = t_{j - 1} \ne s_{i - 1} \ne t_j\)。
260. CF1934E Weird LCM Operations
挖掘一些性质。
发现对于两两互质的一对 \((x, y, z)\),操作一次之后 \(\gcd = x, y, z\) 的限制都会被满足。
但是我们对于全部数都划分成这样的三元组要划分 \(\frac{n}{3}\) 个,但是只能操作 \(\frac{n}{6}\) 个。
发现 \(\le \frac{n}{2}\) 的元素不用被操作,因为 \(2x\) 的倍数一定在序列中。
于是考虑怎么对 \(> \frac{n}{2} - O(1)\) 的元素,划分成若干个两两互质的三元组。
发现对于 \(x \bmod 4 = 3\) 或 \(2\),\(x \sim x + 11\) 能划分成 \(4\) 个三元组。
当 \(n \bmod 4 = 0\) 或 \(3\) 时可以先操作 \((1, n - 1, n)\) 使得 \(n \gets n - 2\)。
但是这样小数据会有问题。\(n \le 12\) 打表即可。
261. [ABC343G] Compress Strings
比较搞笑,ABC 场上甚至不会。
把是别的串的子串的串扔掉,剩下的重叠部分一定是一段后缀和一段前缀重叠。
然后就转化成最小哈密顿路径了。
262. CF1945H GCD is Greater
感觉是这场唯一比较有趣的题?
首先明确一点:先手只会选 \(2\) 个数,因为数多了 \(\gcd\) 会变小,而且对方的 \(\text{and}\) 会变大。
所以对于某一位,若 \(0\) 的个数 \(\ge 3\) 那么对方的按位与这一位一定是 \(0\)。
所以若 \(0\) 的个数 \(\le 2\),那么可能会选这一位是 \(0\) 的,导致对方的按位与这一位是 \(1\)。把它们加入一个集合 \(S\) 中。
对每一位做这一步后 \(S\) 的大小为 \(O(\log V)\)。枚举 \(S\) 中的每个元素,再 \(O(n)\) 枚举另外一个选什么,\(O(\log V)\) check 一下即可(\(O(\log V)\) 是因为要算 \(\gcd\)。还要写一个 ST 表查询区间按位与)。
令 \(T = \{1, 2, \ldots, n\} \setminus S\)。此时还没有考虑选 \(T\) 中的数。但是因为选 \(T\) 中的任意两个数,剩下的数的按位与都等于原序列的按位与,所以我们只可能选 \(T\) 中两两 \(\gcd\) 最大的两个数,设它们为 \(a_x, a_y\)。特殊考虑一下它们即可。
总时间复杂度 \(O(n (\log n + \log^2 V))\)。
263. CF1530H Turing's Award
考虑时光倒流,然后钦定格子上的数一定属于 LIS(除了 \(a_n\))。
可以得到一个 dp,\(f_{i, j}\) 为 LIS 长度为 \(i\),目前考虑了 \(a_j, a_{j + 1}, \ldots, a_n\),\(a_j\) 被添加至 LIS 的最左边,LIS 最右边的最小值;对称地设 \(g_{i, j}\) 表示 \(a_j\) 被添加至 LIS 的最右边,LIS 最左边的最小值。
然后有一个经典结论,随机排列的 LIS 是 \(O(\sqrt{n})\) 的,所以 dp 第一维是 \(\sqrt{n}\) 的。转移使用树状数组优化,总时间复杂度 \(O(n \sqrt n \log n)\)。
264. P10254 口吃
dp 逆序对为 \(k\) 的排列数有个经典做法是从大到小插入,枚举每个数插入的位置就知道它左边有几个数比它大。
然后发现 \(i\) 可以拆成 \(i\) 左边 \(p_j \ge p_i\) 的部分和 \(p_j < p_i\) 的部分(拆贡献!),然后随便 dp 一下前缀和优化就做完了。
265. P10255 一首诗
这题怎么这么抽象啊?
前面的推导和 CF1928F Digital Patterns 一模一样。发现我们要支持什么 \(b_i\) 区间加等差数列,区间加一个数,然后还要查全部的异或,直接做非常困难。
考虑根号分治,对于 \(i \le \sqrt{n}\) 的 \(b_i\) 可以直接算;对于 \(i > \sqrt{n}\) 的 \(b_i\),发现只有长度 \(> \sqrt{n}\) 的段才会影响它们。把这些段拎出来,段数是 \(O(\sqrt{n})\) 的。然后要干一个类似查询等差数列异或和的东西,但是等差数列公差 \(\le \sqrt{n}\),然后直接预处理就做完了。
266. CF1566F Points Movement
考虑把包含一个点的区间和包含其他小区间的区间扔掉,剩下的区间左端点单增右端点也单增,并且是两个点中间夹着若干个区间的形式。
有一个很重要的套路是延迟计算贡献。我们把 \(a_{i - 1}\) 往右走的贡献和 \(a_i\) 往左走的贡献一起放在 \(f_{i - 1} \to f_i\) 的转移计算,然后设 \(f_{i, 0/1}\) 表示 \(i\) 先往左走还是先往右走的最小距离,枚举 \(a_{i - 1}\) 往右走到哪个点就行了。
267. P5693 EI 的第六分块
考虑沿用最大子段和的线段树维护方法,即一个点维护 \((pmx, smx, ans, sum)\)。
我们把它们都看成是一次函数,然后修改阈值 \(t\) 的定义为子树内的所有这些信息的最大函数第一次发生变化的最小需要加的 \(x\)。然后套 KTT 板子即可。
268. CF1178G The Awesomest Vertex
我们记 \(A_u = \sum\limits_{v \in R(u)} a_v, B_u = \sum\limits_{v \in R(u)} b_v\),然后把子树拍平到序列。问题变为:
- 区间对 \(A_i\) 加正数
- 求 \(\max\limits_{i = l}^r |A_i| \times |B_u|\)
\(|B_u|\) 是固定的,所以可以预先取绝对值。考虑 \(|x| = \max(x, -x)\),所以开两棵 KTT 维护即可(一个的 \(b_i\) 是 \(B_i\) 另一个是 \(-B_i\))。
269. CF1948G MST with Matching
这个题是真抽象。感觉第一步想到就做完了,第一步想不到就是真做不出来/kk。
发现一个很令人惊讶的事情:树是二分图。所以最大匹配等于最小点覆盖。
\(O(2^n)\) 枚举最小点覆盖,然后算一下最小生成树即可。时间复杂度 \(O(2^n n^2 \log n)\),\(O(\log n)\) 是并查集复杂度。
270. CF1948F Rare Coins
看到这种很像范德蒙德卷积的,一定要往范德蒙德卷积上靠!
记住 \(\binom{n}{m} = \binom{n}{n - m}\)!
设 \(x\) 为金币数量,\(y\) 为银币数量,\(P\) 为总金币数量,\(Q\) 为总银币数量。我们直接把答案分子的式子列出来:
预处理组合数前缀和即可。时间复杂度线性。
271. CF1830F The Third Grace
考虑 dp,设 \(f_i\) 为选第 \(i\) 个点的最大得分。这里为了方便,把第 \(i\) 个点的贡献放到往右边转移的时候再计算。
有 \(f_j = \max f_i + c_{i, j} p_i\),其中 \(c_{i, j}\) 为 \(l \le i \le r < j\) 的区间数量。
考虑扫描线,扫右端点,同时 KTT 维护 \(f_i + c_{i, j} p_i\),当 \(j \to j + 1\) 时把所有 \(r = j\) 的区间的 \([l, r]\) 的值加上 \(p_i\)。还要支持把单点修改成 \(f_i\)。套板子即可。
挺抽象的,\(O(n \log^3 n)\) 过 \(10^6\)。
272. CF573E Bear and Bowling
考虑一个贪心:每次选对答案增量最大的元素,在这个过程中的最大权值即为答案。
考虑动态维护选择第 \(i\) 个元素后答案的增量 \(f_i\)。相当于若选了 \(p\),则 \(i \in [1, p - 1], f_i \gets f_i + a_p\);\(i \in [p + 1, n], f_i \gets f_i + a_i\);\(f_p \gets -\infty\)。
容易看出这是 \(f_i = k_i x_i + b_i\) 的形式,套 KTT 板子即可。区间加 \(b_i\) 直接打标记就行。
273. P9151 计数题
首先转化操作为:
- 删掉 \(2\) 个相邻的不同字符;
- 选择 \(3\) 个相邻的相同字符,删掉 \(2\) 个。
发现最后得到的串一定是原来的子序列。考虑建一个类似自动机的东西,每个位置的 \(0, 1\) 出边分别指向要让下一个字符是 \(0\) 或 \(1\) 的最前的位置。然后再 dp 就行。
考虑建自动机。对于 \(s_i = 0\),\(1\) 的出边就直接指向下一个 \(1\) 即可;\(0\) 的出边就指向下一个 \(j\) 使得 \(s_j = s_{j - 1} = 0\),此时 \([i + 1, j - 1]\) 一定能删除,因为可以把 \([i + 1, j - 2]\) 删成一个字符 \(c\),然后再删除 \(s_{j - 1}\) 和 \(c\)。注意要保证出边指向的位置和 \(i\) 的奇偶性不同。
感觉算本质不同的子序列建自动机是常见套路?
274. P9288 [ROI 2018] Innophone
我们可以强制让 \(a, b\) 必须顶到某一个 \(x_i, y_i\),容易发现这样不会使答案变劣。
考虑枚举 \(a\) 然后扫描线,维护有哪些元素不满足第一个条件,KTT 维护 \(b\) 取每个值的权值和,那么贡献就是形如区间加 \(k_i\)。
275. [ARC173E] Rearrange and Adjacent XOR
不妨考虑最后的结果可以成为哪些 \(a_i\) 的组合。为了方便分析,我们令 \(a_i = 2^{i - 1}\)。
进行一次操作后,所有 \(\text{popcount}(a_i)\) 都为偶数。所以一个 \(x \in [0, 2^n - 1]\) 能被生成出来的必要条件是 \(\text{popcount}(x)\) 为偶数。
然后通过打表可以发现:
- 对于 \(n = 2\) 或 \(n \bmod 4 \ne 2\),任意一个 \(x \in [1, 2^n - 1]\) 且 \(\text{popcount}(x)\) 为偶数的 \(x\) 都能被生成出来。
- 对于 \(n \ne 2\) 且 \(n \bmod 4 = 2\),任意一个 \(x \in [1, 2^n - 2]\) 且 \(\text{popcount}(x)\) 为偶数的 \(x\) 都能被生成出来。
考虑归纳证明。因为 \(a\) 中元素可以重排,所以不妨只考虑 \(2^{2k} - 1\)(\(k \ge 1\))能否被生成出来:
- \(k\) 为偶数,做一次操作后序列变成 \(a = [2^0 + 2^1, 2^1 + 2^2, \ldots, 2^{n - 2} + 2^{n - 1}]\)。因为 \(k\) 为偶数,所以最后剩下的值可以为 \(a_1 \oplus a_3 \oplus \cdots \oplus a_{2k - 1}\),所以成立。
- \(k\) 为奇数,不妨让一开始的 \(a\) 的前 \(2k + 1\) 个元素为 \(2^0, 2^1, \ldots, 2^{2k - 2}, 2^{n - 1}, 2^{2k - 1}\)(要求 \(2k < n\))。做一次操作后,因为 \(k + 1\) 为偶数且当 \(n - 1 > 2\) 时 \(k + 1 \ne n - 1\),所以最后剩下的值可以是 \(a_1 \oplus a_3 \oplus \cdots \oplus a_{2k - 1} \oplus a_{2k}\),所以成立。
于是现在问题变成了:选一个 \(a\) 中的包含偶数个元素的子集,最大化异或和,同时还可能有不能选全集的限制。
对于没有限制的情况,发现 \(a\) 中的任意一个包含偶数个元素的子集的异或和都可以表示成 \(a_1 \oplus a_2, a_1 \oplus a_3, \ldots, a_1 \oplus a_n\) 的一个子集的异或和。所以直接把这些数塞进一个线性基,然后查询即可。
对于有限制的情况,我们不妨钦定一个数不被选,删掉这个数,就转化成了没有限制的情况。
时间复杂度 \(O(n^2 \log V)\)。
276. [ARC169D] Add to Make a Permutation
设取模前的排列为 \(b\)。发现 \(b\) 取 \(x, x + 1, \ldots, x + n - 1\) 最优,同时 \(b\) 还要满足:
- \(\sum\limits_{i = 1}^n b_i - a_i \equiv 0 \pmod m\);
- \(\max\limits_{i = 1}^n b_i - a_i \le \frac{s}{m}\),其中 \(s = \sum\limits_{i = 1}^n b_i - a_i\)。
满足第一个条件后,\(x\) 一次可以增加 \(\frac{m}{\gcd(n, m)}\)。根据第二个条件算 \(x\) 最少要增加几次即可。
277. CF1943E1 MEX Game 2 (Easy Version)
MEX \(\Rightarrow\) 二分,所以先二分答案 \(k + 1\),变成问 \(0 \sim k\) 能否都能取。
容易发现只关心 \(a_0, a_1, \ldots, a_k\) 形成的可重集,所以先排序。
Alice 的策略是固定的,每次找最小的取走,最小值为 \(0\) 就输了。Bob 如果想在第 \(p\) 轮使 Alice 输,那么它只会取 \(0 \sim p\) 中的值。同时为了维护可重集的相对顺序,会从后往前,不断“推平”差值 \(a_i - a_{i - 1}\)。
朴素地实现即可。时间复杂度 \(O(m^4 \log m)\)。
278. JSC2022 Final E Circular Sushi / 2024.3.26 模拟赛 T1 礼物(gift)
分析可得 \(t\) 的分母为 \(2^l\) 涵盖了所有情况。设 \(t\) 的分子为 \(p\)。
通过 \(a_i + t v_i \equiv 0 \pmod 2^l\) 可以推出形如 \(p\) 二进制下的后 \(k\) 位为某个数时答案会增加 \(w_i\)。从低位到高位建 01Trie,相当于子树加,树上差分即可。
279. P5853 [USACO19DEC] Tree Depth P / 2024.3.26 模拟赛 T2 逆序对(inv)
发现 \(j\) 是笛卡尔树上 \(i\) 的祖先当且仅当 \(\min\limits_{i = \min(i, j)}^{\max(i, j)} p_i = p_j\)。
考虑算逆序对数量为 \(m\) 的排列,相当于从左往右考虑相对排名,第 \(i\) 个数可以对逆序对数造成 \(0, 1, \ldots, i - 1\) 的贡献,即乘上多项式 \(1 + x + x^2 + \cdots + x^{i - 1}\)。
考虑枚举 \(|i - j|\),钦定一个方向填数(比如先往 \(j\) 的方向填,再往另一个方向填)。那么若 \(j\) 在 \(i\) 左侧就产生 \(0\) 个逆序对,否则产生 \(|i - j|\) 个。相当于把 \(j\) 的贡献删掉,即除掉多项式 \(1 + x + x^2 + \cdots + x^{|i - j| - 1}\)。大除法可以直接 \(O(n^2)\) 差分做。所以最后时间复杂度是 \(O(n^3)\)。
280. Gym103409H Popcount Words / 2024.3.26 模拟赛 T3 字符串(word)
暴力就直接建出询问串的 AC 自动机,然后把 \(S\) 在 AC 自动机上走一遍,给走到的每个点的值加 \(1\),最后 fail 树上子树和就是一个点的答案。
发现 \(\text{popcount}(x) \bmod 2\) 是一个倍增的结构,初始有一个 \(0\),每次复制一份拼上去然后异或 \(1\)。
根据线段树的结构可以把 \([l_i, r_i]\) 拆成 \(O(n \log V)\) 个“整”区间。考虑倍增,容易求出 \(f_{k, i, j}\) 表示从 AC 自动机上的点 \(i\) 跳长度为 \(2^k\) 且开头第一个数是 \(j\) 的整区间跳到哪个点。
然后在每个“整区间”的起始点打 tag。设 \(g_{k, i, j}\) 为要跳长度为 \(2^k\) 且开头第一个数是 \(j\) 的整区间,需要把这些点的答案加上 \(g_{k, i, j}\)。考虑下传 tag 即可,即 \(2^k\) 拆成两个 \(2^{k - 1}\)。
所以时间复杂度就是 \(O(n \log V)\)。
281. CF417E Square Table
考虑若构造出来一行和一列的方案,那么直接让 \(c_{i, j} = a_i \times b_j\) 即可。
构造一行的方案可以直接搜 \(\le 16\) 的平方数,可过。
282. CF1936E Yet Yet Another Permutation Problem
首先设 \(a_i = \max\limits_{j = 1}^i p_j\),\(b_i = \max\limits_{j = 1}^i q_j\)。
直接容斥,钦定有多少值不同的 \(a_i\) 使得 \(a_i = b_i\)。然后再把钦定的每种值转化成每种值第一次使得 \(a_i = b_i\) 的位置 \(i\)。
也就是说我们现在要钦定一些位置,满足 \(a_i = b_i\),且不存在 \(j \in [1, i - 1]\) 使得 \(a_j = b_j = a_i\)。
考虑 dp,设 \(f_i\) 表示考虑了 \([1, i]\),当前最后一个被钦定的位置是 \(i\),每种方案的容斥系数之和。
转移枚举上一个被钦定的位置 \(j\)(需要满足 \(a_j \ne a_i\))。
- 若 \(a_i = a_{i - 1}\),说明 \(a_{i - 1} \ne b_{i - 1}\),那么 \(p_i = a_i\)。\([j + 1, i - 1]\) 中相当于从 \(a_i - 1 - j\) 个数中依次选 \(i - j - 1\) 个数填进去,有 \(f_i = -\sum\limits_{j = 0}^{i - 1} [a_j \ne a_i] f_j \frac{(a_i - 1 - j)!}{(a_i - i)!}\)。
- 若 \(a_i \ne a_{i - 1}\),我们可以从 \([j + 1, i]\) 中选一个位置 \(k\) 使得 \(p_k = a_i\)(方案数为 \(i - j\)),然后再从 \(a_i - 1 - j\) 个数中依次选 \(i - j - 1\) 个数填进空位,有 \(f_i = -\sum\limits_{j = 0}^{i - 1} [a_j \ne a_i] f_j \frac{(a_i - 1 - j)!}{(a_i - i)!} (i - j)\)。
初值为 \(f_0 = 1\)。答案即为 \(\sum\limits_{i = 0}^{n - 1} f_i (n - i)!\)。
暴力转移是 \(O(n^2)\) 的。观察转移形式很像可以分治 NTT 的样子,但是又不是传统的分治 NTT 形式(因为贡献形式是 \(f(i) = \sum f(j) g(a_i - j)\))。不妨先尝试 cdq,每次计算 \([l, mid] \to [mid + 1, r]\) 的贡献。
首先 \(a_j \ne a_i\) 的限制是好解决的,可以直接把 \(a_j = a_i\) 的情况减掉,就是分治过程中对于 \(i \in [l, mid], a_i = a_{mid}\) 的所有 \(i\) 转移到每个 \(j \in [mid + 1, r], a_j = a_{mid}\) 的每个 \(j\) 贡献相同,直接相加即可。
然后我们现在希望处理出 \(g_i = \sum\limits_{j = 0}^{i - 1} f_j (a_i - 1 - j)!\) 和 \(h_i = \sum\limits_{j = 0}^{i - 1} f_j (a_i - 1 - j)! j\)。两者类似,只考虑如何计算 \(g_i\)。
相当于我们现在要让 \([l, mid]\) 的 \(f\) 卷上 \([a_{mid + 1} - 1 - mid, a_r - 1 - l]\) 的阶乘,贡献到一个数组 \(c\),那么 \(g_i\) 得到的贡献是 \(c_{a_i - 1}\)。
因为 \(a\) 序列单调不降且值域为 \([0, n]\),所以复杂度和普通的分治 NTT 一样,是 \(O(n \log^2 n)\)。
283. CF1874F Jellyfish and OEIS
感觉很有启发意义!
直接上容斥,钦定一些被要求的区间形成子排列,容斥系数为区间数的 \(-1\) 次方。
对于这种区间的容斥有一个很强的性质,对于两个相交但不包含的区间 \(l_1 < r_1 \le l_2 < r_2\),添加区间 \([r_1, l_2]\) 后方案数相同,容斥系数相反,所以抵消了。
所以我们只用考虑区间不交或包含的情况。考虑把这些区间连成树形结构后区间 dp,设 \(f_{l, r}\) 为 \([l, r]\) 内每种方案的容斥系数之和。一个区间的所有儿子不一定能把它占满,所以方案数还要乘一个散点个数的阶乘。于是再记 \(g_{l, r, x}\) 为 \([l, r]\) 内有 \(x\) 个散点,每种方案的容斥系数之和。
转移枚举 \(l\) 开始的是一个儿子还是散点即可。时间复杂度 \(O(n^4)\)。
284. CF1821F Timber
判定一个方案的合法性容易,贪心能往左倒就往左倒即可。
可以先把每棵树占的区间确定下来,把树的方案数转化为区间的方案数。考虑第 \(i\) 棵树占的最右边的位置 \(p_i\),若 \(p_i - p_{i - 1} \ge 2k + 1\) 那么第 \(i\) 棵树只能往左倒,否则两边都可以,乘一个 \(2\) 的系数。
若设 \(f_i\) 为恰好有 \(i\) 个长度为 \(2k + 1\) 的区间,那么答案为 \(\sum\limits_{i = 0}^m 2^{m - i} f_i\)。
求 \(f_i\) 考虑二项式反演,设 \(g_i\) 为钦定有 \(i\) 个长度为 \(2k + 1\) 的区间,那么插板法可得 \(g_i = \binom{m}{i} \binom{n - i(2k + 1) - (m - i)(k + 1) + m}{m}\)。有 \(f_i = \sum\limits_{j = i}^m \binom{j}{i} (-1)^{j - i} g_j\):
最后一步用的是二项式定理。然后直接 \(O(n)\) 算即可。
285. CF981G Magic multisets
傻逼题,被诈骗了。
大小每次 \(\times 2\) 或 \(+ 1\),每个值开个 ODT 记录哪些极长的包含或不包含它的段,线段树维护可重集大小即可。
286. CF1776N Count Permutations
考虑从一个格子开始,若下一个字符是 <
那么向右走,否则向上走,那么走的路径形成了一个斜杨表,需要求这个斜杨表填 \([1, n]\) 且互不重复的数的方案。
利用斜杨表钩长公式可得答案为:
其中 \(P\) 是一条从左下角到右上角的路径。
考虑 dp 求那个东西。感受一下一条钩长很大的路径对答案的贡献可以忽略,所以只考虑和边界距离 \(\le 500\) 的格子,然后再 dp 即可。
卡精度/tuu。
287. CF1698F Equal Reversal
考虑 \(a_i \to a_{i + 1}\) 形成一个图,并且 \(a\) 是这个图的一个欧拉路径。
一个比较常用的套路是找到第一个 \(a_i \ne b_i\) 的位置,然后想办法把它变得相等。也就是说在某个时刻 \(a\) 中有 \(u \to v_1\),\(b\) 中有 \(u \to v_2\),其中 \(v_1 \ne v_2\)。
考虑在 \(a\) 中之后肯定会有一个 \((u, v_2)\),如果方向是 \(v_2 \to u\) 那么直接翻转这一部分即可,否则方向是 \(u \to v_2\),此时若之后没有包含这条边的环就寄了(因为这部分不在一个环内,而 \(a\) 和 \(b\) 相同的必要条件是连出来的有向图相同)。否则翻转任意一个包含这条边的环,然后再做一遍第一步即可。
操作次数是 \(2n\) 级别的,时间复杂度 \(O(n^3)\)。
288. CF1155E Guess the Root
唐氏题 1。
插值插出多项式,枚举根即可。
289. CF356D Bags and Coins
唐氏题 2。
每个连通块是一个链最优,\(s\) 的限制实际上限制了根的 \(a_i\) 的和。
\(a\) 的最大值一定要选。剩下的做个 01 背包即可。
因为要输出方案,但是全部存空间会炸,所以可以每 \(3\) 个存一个,枚举每 \(3\) 个的 \(2^3\) 种组合即可。
290. CF331D3 Escaping on Beaveractor
没看到线段互不相交,看到了就是唐氏题了。
扫描线处理出每条线段走到的下一条线段是哪条,因为线段互不相交所以一条线段上的所有点都会一直沿着线段方向走完整条线段而不用考虑中间被断开的情况。为了方便可以把每个询问都视为一条线段。
然后就可以倍增了。
291. CF1698G Long Binary String
把前导 \(0\) 去掉,看成生成函数 \(F(x)\),那么就是求最小的 \(k\),使得存在另一个多项式 \(G(x)\) 满足:
等价于:
BSGS 即可,就是注意到 \(k \le 2^{\deg F(x)}\),可以把 \(k\) 拆成 \(aB - b\),那么:
然后 BSGS 就行了,对多项式取模因为是模 \(2\) 意义下所以可以用一些位运算代替。时间复杂度 \(O(n 2^{\frac{n}{2}})\)。
292. [ARC175E] Three View Drawing
下文令 \(m\) 为原题面的 \(k\)。
题目条件很奇怪,考虑有没有什么比较好用的策略。
发现对于任意一个三元组 \((a, b, c)\),其中 \(a, b, c\) 不全相等,那么同时添加 \((a, b, c), (b, c, a), (c, a, b)\),\(\{(x_i, y_i)\}, \{(y_i, z_i)\}, \{(z_i, x_i)\}\) 三个集合都会同时添加 \((a, b), (b, c), (c, a)\)。特别地,对于三元组 \((a, a, a)\),添加它后三个集合都会同时添加 \((a, a)\)。所以如果原来的合法,那么添加后也合法。
所以考虑找出尽可能多组 \(\{(a, b, c), (b, c, a), (c, a, b)\}\)。发现可以直接令 \(a + b + c \equiv 0 \pmod n\)。这样若 \(n \bmod 3 = 0\),除了 \((0, 0, 0), (\frac{n}{3}, \frac{n}{3}, \frac{n}{3}), (\frac{2n}{3}, \frac{2n}{3}, \frac{2n}{3})\),其他 \(n^2 - 3\) 个 \((a, b, (-a - b) \bmod n)\) 都恰好在一个“组”内。若 \(n \bmod 3 \ne 0\),除了 \((0, 0, 0)\),其他 \(n^2 - 1\) 个 \((a, b, (-a - b) \bmod n)\) 都恰好在一个“组”内。
所以一个想法是把 \(m\) 分成 \(3 \left\lfloor\frac{m}{3}\right\rfloor\) 和 \(m \bmod 3\) 两部分,前者就直接取 \(\left\lfloor\frac{m}{3}\right\rfloor\) 组 \((a, b, c), (b, c, a), (c, a, b)\),后者就取 \(m \bmod 3\) 组 \((a, a, a)\)。
但是你发现你在 \(n \bmod 3 \ne 0\) 且 \(m \bmod 3 = 2\) 的时候寄了,因为此时形如 \((a, a, a)\) 的三元组只有一个 \((0, 0, 0)\),但是上面的方法需要 \(2\) 个。发现此时 \(m \le n^2 - 2\),所以可以直接把一组 \((a, b, c), (b, c, a), (c, a, b)\) 拆掉,比如拆 \((1, 1, (-2) \bmod 3)\),把它变成 \((1, 1, 1)\) 即可。
293. CF1284E New Year and Castle Construction
枚举被包围的点,以这个点为原点将剩下的点极角排序,那么不符合条件的四元组一定能被一个半圆包含。双指针扫即可。时间复杂度 \(O(n^2 \log n)\)。
294. CF1534F2 Falling Sand (Hard Version)
智慧题。
Easy Version 就直接建图缩点,答案就是入度为 \(0\) 的强连通分量个数。
Hard Version 考虑取出每一列从下往上的第 \(a_i\) 个沙子,称它们为关键点。
仍然建图后缩点。如果关键点 \(u\) 能到达关键点 \(v\) 那么可以把 \(v\) 删掉。然后我们有结论,每个点到达的关键点一定是一段区间。
拓扑排序求出每个点的区间后就变成了经典问题,给你一些区间,选出最少个区间使得覆盖全集。每次贪心地选范围内的能覆盖到最右边的区间即可。
295. P9732 [CEOI2023] Trade
考虑第一问,设一个区间的价值 \(g(l, r)\) 为 \(f(l, r) - a_r + a_{l - 1}\),其中 \(a_i = \sum\limits_{j = 1}^i c_j\),\(f(l, r)\) 为 \([l, r]\) 中最大的 \(k\) 个 \(b_i\) 的和,设 \(p_i\) 为以 \(i\) 为右端点,区间价值最大的左端点,那么 \(p_i\) 满足决策单调性,也就是 \(p_i \le p_{i + 1}\)。
证明即证:
其中 \(a \le b \le c \le d\)。化简得:
即证:
考虑 \([a, b + 1]\) 相当于是 \([a + 1, b]\) 的加入两个单点 \(a\) 和 \(b\),它们能替换 \([a + 1, b]\) 中前 \(k\) 大的最小值和次小值,但是如果换成 \([a, b]\) 和 \([a + 1, b + 1]\),那么 \(a\) 和 \(b\) 只能分别替换 \([a + 1, b]\) 的最小值,所以 \([a, b], [a + 1, b + 1]\) 一定不劣。
所以第一问就可以直接基于这个利用分治算,\(g(l, r)\) 可以维护 \(l, r\) 的指针然后移动指针的同时用树状数组维护。
对于第二问,对于每个点求最大的 \(p_i\),然后把所有 \(g(p_i, i)\) 等于答案的 \([p_i, i]\) 从左往右扫,那么右端点为 \(i\),左端点在 \(l \sim p_i\) 之间(其中 \(l\) 为上一个 \(g(p_j, j)\) 等于答案的 \(p_j\))的区间会对第二问的答案有贡献。就相当于现在有一些形如 \((l, r, k)\) 的操作,意义是把 \(l \sim r\) 且 \(b_i \ge k\) 的 \(i\) 的答案设为 \(1\),那么直接对 \(k\) 扫描线,链表或并查集维护全部 \(b_i \ge k\) 且还没被覆盖过的点即可。
总时间复杂度 \(O(n \log^2 n)\)。
296. [AGC048F] 01 Record
反转 \(S\),那么相当于用一些形如 1010
的串覆盖 \(S\)。
先贪心地每次从 \(S\) 中取出最长的串,设取出的串的长度为 \(l_1, l_2, \ldots, l_m\)。
考察一个可重集 \(x_1, x_2, \ldots, x_n\) 需要满足的条件。发现充要条件是:
- \(\sum l_i = \sum x_i\)
- \(\forall i \in [1, n], \sum\limits_{j = 1}^i \left\lfloor\frac{l_i}{2}\right\rfloor \ge \sum\limits_{j = 1}^i \left\lfloor\frac{x_i}{2}\right\rfloor\)(相当于限制前 \(i\) 个串中 \(1\) 的个数)
- \(\forall i \in [1, n], \sum\limits_{j = 1}^i \left\lceil\frac{l_i}{2}\right\rceil \ge \sum\limits_{j = 1}^i \left\lceil\frac{x_i}{2}\right\rceil\)(相当于限制前 \(i\) 个串中 \(0\) 的个数)
必要性显然,充分性大概就是考虑把 \(x\) 一步步调整成 \(l\) 而不破坏第 \(2, 3\) 条性质。
297. CF1942E Farm Game
不妨假设先手的牛在后手的牛左边,右边是对称的。
直接给出结论:先手必败当且仅当全部 \(b_i - a_i\) 为奇数。
证明考虑归纳,首先 \(\forall i \in [1, n], b_i - a_i = 1\) 是必败态,因为先手只能往左退,最后后手会把先手逼到最左边使得它无法动弹。
然后若存在 \(i\) 使得 \(b_i - a_i\) 为偶数,那么先手可以选择这些 \(i\) 然后把这些牛往右移,让后手面对这个 \(b_i - a_i\) 都为奇数的必败的局面。
计数是简单的。考虑数必败态,枚举 \(\sum\limits_{i = 1}^n b_i - a_i - 1 = t\),那么相当于要把其他的空隙分成 \(n + 1\) 份分别插入开头、末尾和第 \(2i\) 和第 \(2i + 1\) 头牛之间,然后对于第 \(2i - 1\) 和第 \(2i\) 的牛之间都要分配偶数个空隙。这些都可以用插板法计算。
时间复杂度 \(O(l)\)。
298. CF277B Set of Points
取两个凸函数即可。