一些题(八)

[CF1603E] A Perfect Problem

考虑对不降序的 \(\{a_i\}\) 进行计数,调整可证此时是 perfect 的当且仅当它所有前缀都是 good 的。同时由于最大值最多只有 \(n+1\),所以对于每个前缀始终有 \(\sum (a_i-a_1)\leq a_1\)。那么可以枚举 \(a_1\) 后设 \(f_{i,j,k}\) 表示填完了 \(\leq i\) 的数,填到了位置 \(j\),当前 \(\sum(a_i-a_1)\) 的值为 \(k\) 的方案数。这样状态是 \(O(n^3)\) 的,转移由调和级数是 \(O(\log n)\) 的,但还要枚举 \(a_1\) 无法接受。继续分析,发现始终有 \(a_i\geq i\),再结合 \(\sum(a_i-a_1)\leq a_1\leq n+1\)\(a_1\geq n-O(\sqrt{n})\),于是只用枚举 \(O(\sqrt{n})\) 个数,能过。

https://codeforces.com/contest/1603/submission/140229092

[JOISC2017] 港湾設備

对于 \(i,j\),若 \(A_i<A_j\) 那么它们不能入同一个栈当且仅当 \(B_i<B_j\)。于是可以用一个栈顺着扫每一个时刻来辅助并查集维护那些点对一定在/不在同一个栈中。具体地,当加入一个 \(B_i\) 时,将栈顶到对应 \(A_i\) 的所有元素合成一个,它们肯定要在一个栈中且这个栈与 \(i\) 的栈不同,同时判断下是否有矛盾。这样均摊只有 \(O(n)\) 次并查集操作。

https://atcoder.jp/contests/joisc2017/submissions/27976873

[CERC2017] Cumulative Code

容易 \(O(2^n)\) 求出一棵深为 \(n\) 的满二叉树的 purfer 序列。考虑均摊复杂度,预处理出深度为 \(\lfloor n/2\rfloor\) 的、根有父亲的满二叉树的 purfer 序列每一位关于根标号 \(x\) 的函数,其一定能写成 \(\lfloor ax/2\rfloor+b\) 的形式。这样回答询问时可以仅递归 \(\lceil n/2\rceil\) 层然后利用预处理出的信息(除了最右的那棵子树)。总复杂度为 \(O(q2^{n/2})\)

https://www.luogu.com.cn/record/65331710

[CF1601F] Two Sorts

考虑建出字典树,那么 \(i-a_i\) 可以替换为 \(dfn_i-i\),其中 \(dfn\) 为在字典树上的 dfs 序。考虑均摊复杂度,设 \(n\) 的位数为 \(k\),那么可以预处理出深度为 \(\lfloor k/2\rfloor\) 的满字典树的 \(dfn\) 的相对顺序。这样只用递归前 \(\lceil k/2\rceil\) 层,以及其中 \(\tilde{O}(1)\) 个节点的后 \(\lfloor k/2\rfloor\) 层就能求出答案。复杂度 \(\tilde{O}(\sqrt{n})\)

[CF1605F] PalindORme

以下将每个数看作集合。考虑如何判定一个序列合法,发现可以每次选择两个相同的数丢到两边,然后将数下的数集合差上它,于是序列合法当且仅当最后只剩下至多一个数。设 \(f_{n,k}\) 表示满足 \(|\bigcup_ia_i|=k\) 的合法序列 \(\{a_i\subset[k]\}_{i=1}^n\) 的数量。那么可以枚举什么时候不合法来容斥得到 \(f_{n,k}=(2^n-1)^k-\sum_{i\leq n-2,2|i}\sum_{j<k}{n\choose i}{k\choose j}f_{i,j}g_{n-i,k-j}\)。其中 \(g_{n,k}\) 表示满足 \(|\bigcup_ia_i|=k\) 的元素互不相同的序列 \(\{a_i\subset[k]\}_{i=1}^n\) 数量,可以用二项式反演得到,为 \(n!\sum_{i=0}^k{k\choose i}(-1)^{k-i}{2^i\choose n}\)。于是预处理出 \(g\) 后可以 \(O(n^2k^2)\) 求出答案。

[JOISC2017] 鉄道旅行

显然可以只保留每个车站到往左/右第一个流量不小于它的车站的双向边,那么可以考虑起点终点一起往流量高的地方跳直到重合。考虑用倍增求出每个车站往左/右跳若干步最远能到哪,注意可能左右横跳所以转移时要一起更新。求答案时先将左边的尽量往右跳,再将右边的尽量往左跳,这样流量小的就一定能一步跳到流量大的上了。

[CF1610H] Squid Game

列出线性规划式子,转对偶。感性理解下它的意义就能树 dp 了。具体细节摆了。

https://codeforces.com/contest/1610/submission/141390219

[CF1615F] LEGOndary Grandmaster

注意到给定的操作等价于将字符串奇数位取反后交换相邻的 0 和 1。之后的二维 dp 就很显然了。

[CF1616F] Tricolor Triangles

注意到一个三角形内的条件等价于边颜色之和 \(\bmod 3=0\),于是直接高斯消元即可。因为三角形数量很少,所以复杂度是对的。另外 \(\bmod 3\) 高斯消元也可以 bitset 优化。

[CF1616H] Keep XOR Low

考虑枚举所选集合中最大的异或与 \(x\) 不同的最高位。维护一个在字典树上的节点 \(u\),表示所选的集合必须包含于 \(u\) 的子树,初始为根。若 \(x\) 当前位为 0,那么 \(u\gets son_{u,0}\)。否则若钦定在当前位不同,方案数为 \(son_{u,0/1}\) 的非空子集数。不然将 \(u\) 拆成两个节点 \(a=son_{u,0},b=son_{u,1}\),表示所选的集合必须为 \(a\) 子树的非空子集和 \(b\) 子树的非空子集的并。之后 \(a,b\) 的变化可以类似维护。复杂度 \(O(n\log x)\)

[CF1580F] Problems for Codeforces

首先考虑 \(n\) 为偶数的情况,注意到条件等价于 \(a_1\le m-1-a_2\ge a_3\le \cdots\le m-1-a_n\ge a_1\),于是可以对 “\(\le\)“ 容斥。具体地,需要将一些 “\(\le\)” 替换为 “\(>\)“,其它的无限制。由于不可能同时替换所有,所以最终条件只由若干条形如 \(b_1\ge b_2>\cdots>b_{2k-1}\ge b_{2k}\) 的段拼成,该段的方案数为 \(f_{k}={m+k\choose 2k}\)。考虑到容斥系数,每一段的生成函数即为 \(-\sum_{k>0}f_kz^k\)

接着考虑 \(n\) 为奇数,将 \(<\lceil m/2\rceil\) 的数标上 \(x\),否则标上 \(y\)。那么最终的环一定是由若干个 \(xyx\ldots yx\) 拼成,于是就需要找到它的生成函数。考虑将 \(y\) 减去 \(\lceil m/2\rceil\) 就变成了 \(m\gets \lfloor m/2\rfloor\) 后的上一个问题。但要注意的是当 \(m\) 为奇数时 \(\lfloor m/2\rfloor\)\(x\) 但它只能自成一段,需要特殊考虑。

最后将段拼成环时,若段的生成函数为 \(P(z)\),那么环的生成函数即为 \(zP’/(1-P)\)

https://codeforces.com/contest/1580/submission/141624625

[CF1606F] Tree Queries

考虑固定 \(k\) 的话可以简单 dp 求出每个点的答案。然后发现只有儿子个数 \(>k\) 的点被删去才可能带来收益,于是只用在这些点以及有 \(k\) 询问的点的虚树上跑 dp 即可。这样复杂度是 \(O(n\log n)\) 的。

https://codeforces.com/contest/1606/submission/141703336

原文地址:https://www.cnblogs.com/Y25t/p/15767106.html