26.06 做题记录
SPOJ11414 COT3 - Combat on a tree
考虑对每个子树维护 SG 函数值,如果根节点是白点,我们枚举子树内白点算 SG 值。
考虑如何优化这个过程,维护每个子树的 SG 函数集合,每次需要给整个集合异或,或者合并集合,01trie 维护即可,复杂度 \(O(n \log n)\)。
AT_agc048_d [AGC048D] Pocky Game
考虑剩下的石子形态一定是一段区间,考虑一个区间 dp:\(f_{l,r,x,y,0/1}\) 代表 \([l,r]\) 这个区间,最左边还剩余 \(x\),最右边还剩余 \(y\) 先手 / 后手操作能否必胜。复杂度 \(O(tn^5)\),难以通过,或许可以 bitset 优化一个 \(\omega\)。
两个人每次操作必然拿一个或者拿完,因为其它的方式都可以调整成这两种。所以上面的区间 dp 可以优化到 \(O(tn^4)\)。注意到值域只有 \([0,1]\),考虑最优性换维:
观察到,如果某一堆的石子个数比其他剩下的堆加起来还多,那么谁先碰到那一堆谁就赢了。进一步观察发现,是否胜利和当前操作的堆的石子个数有一定的单调性联系。显然石子越多越容易赢,定义 \(f_{l,r,x,0/1}\) 代表当前先手 / 后手操作,对侧的石子数为 \(x\),想要赢这一侧最少的石子数。考虑转移,我咋不会了,这东西咋转移。
考虑先手的策略,如果此时 \(x<f_{l+1,r,a_l,1}\),那么先手直接取走最左边的一整堆石子一定能赢,否则取完一定赢不了,只取一个,后手策略也是这样。那么也就是说,先后手会一直耗,直到某个人的必胜条件达成。更具体来说,我们发现 \(x\) 并不需要记在状态里面,将状态修改为 \(f_{l,r,0/1}\) 而把 \(x\) 固定为另一侧的 \(a_l\) 或 \(a_r\) 的值。那么对于 \(f_{l,r,0}\) 有转移:
- \(1 \to f_{l,r,0}(a_r < f_{l+1,r,1})\)。
- \(f_{l,r-1,0}-f_{l+1,r,1}+a_r+1 \to f_{l,r,0}(a_r \ge f_{l+1,r,1})\)。
对于 \(f_{l,r,1}\) 的转移同理,时间复杂度 \(O(tn^2)\)。难点主要在于对操作流程的刻画。
CF1147F Zigzag Game
二分图博弈模型是,如果对于任意一组最大匹配起始点均在匹配中,则先手必胜。由于本题是完全二分图,所以如果不考虑边权,先手必胜。
我们希望找到一组最大匹配 \((p_i,q_i)\),使得先手走匹配边,后手走非匹配边,并且都合法。这等价于说,Bob 走完 \(p_i \to q_i\),Alice 走任意的 \(q_i \to p_j\),Bob 可以走 \(p_j \to q_j\)。不妨考虑 Alice 选择 I,那么有要求 \(w(q_i,p_j)>w(p_i,q_i) \wedge w(q_i,p_j)>w(p_j,q_j)\),我们预设第一个成立,也就是不能存在 \(w(p_i,q_i)<w(q_i,p_j)<w(p_j,q_j)\)。
转化形式,得到不能存在 \(-w(q_j,p_j)<-w(p_j,q_i) \wedge w(q_i,p_i) < w(q_i,p_j)\) 。这是一个稳定婚姻问题,可以直接解决,时间复杂度 \(O(n^2)\)。
AT_agc026_f [AGC026F] Manju Game
考虑如果 \(n\) 是偶数,那么先手的一种操作方案是直接选择所有偶数位置或者所有奇数位置,记 \(\sum e,\sum o\) 为偶数位置,奇数位置的和,那么先手至少有 \(\max(\sum e, \sum o)\)。如果先手从中间取,那么后手必然有方案可以取走 \(\sum e\) 或者 \(\sum o\),也就是说 \(\max(\sum e, \sum o)\) 是先手的答案上界。
接着考虑如果 \(n\) 是奇数,分类讨论先手取 \(e\) 还是取 \(o\):
- 如果先手取 \(o\),那么左右两边的子游戏都是后手先手,所以先手的权值 \(\le \sum o\),不如直接取端点处的 \(o\)。
- 如果先手取 \(e\),那么有一边的先手是先手,另一边的先手是原来的后手,后手会选择一段 \(\sum o\) 取走,把 \(\sum e\) 留给先手,然后递归到一个子问题。将递归的过程建树,那么先手会取走一个叶子的 \(\sum o\) 和其他所有叶子的 \(\sum e\)。二分取 $\sum o $ 那段的 \(\delta = \sum o - \sum e\),先手能取到那一段的条件是其余叶子的 \(\sum o - \sum e \ge \delta\)。
时间复杂度 \(O(n \log n)\)。
AT_arc116_f [ARC116F] Deque Game
终于有我会做的题了。考虑 \(k=1\) 怎么做,对 \(n\) 的奇偶性讨论:
- \(n\) 是偶数:先手可以与后手上一步完全对称,所以先手肯定可以拿两个中位数中的任意一个;考虑后手为了不让先手可能拿到其他数,也一定和先手对称操作,所以剩下的值是先手在两个中位数二选一。
- \(n\) 是奇数:先手可以和后手上一步完全对称,所以先手对中间的三个都有机会拿到。考虑后手的操作,首先后手一定会和先手对称操作防止先手拿到这三个以外的数。然后发现后手每一步都和先手对称可以做到恰好一定保留中间的那个数 \(a_m\)。否则后手歪着操作一步,先手可以碰到中间点两边的两个数 \(a_l,a_r\),并且这两个数由先手来选一个较大的。
接下来考虑 \(k>1\) 怎么做,因为 \(n\) 是偶数会导致先后手互换。我们发现,\(n\) 是偶数先手一定比后手优,并且 \(n\) 是奇数先手一定比后手劣。考虑 Alice 一步取 \(n\) 是奇数还是 \(n\) 是偶数,首先如果场上有序列长度为偶数,Alice 肯定不会犯蠢去取长度为奇数的序列,然后如果有其他长度为偶数的序列,那么 Bob 必然不会取这个序列而会取别的长度为偶数的序列。
所以先后手的操作流程形如,两人轮流操作所有长度为偶数的序列,然后一个一个把奇数的序列操作完。最后考虑如何定量一个序列的相对价值,首先只会对长度为偶数的序列衡量价值,因为长度为奇数必然会轮流取。发现算出取头和取尾的价值差的绝对值就是一个序列的价值,排个序即可,时间复杂度 \(O(n \log n)\)。
P10441 [JOIST 2024] 乒乓球 / Table Tennis
如果知道了出度序列 \(d_i\),那么三元环个数为 \(\binom{n}{3} - \sum\binom{d_i}{2}\),考虑对两个出度为 \((a,b)\) 的点调整到 \((a+1,b-1)\),那么三元环数量减少 \(b-a+1\) 个。找到最小的 \(n_0\) 使得可以构造出 \(\ge m\) 条边,每次选两个出度相同的点调整即可,时间复杂度 \(O(n^2)\)。
CF2115F2 Gellyfish and Lycoris Radiata (Hard Version)
好牛啊。首先考虑,操作 \(k\) 次会把数组分为 \(O(k)\) 个段,每个段内插入操作相同,可以用 \(O(k)\) 个形如 \([l,r] \to [l',r']\) 以及有无翻转的信息来维护。由于查询是单点,我们可以 \(O(k)\) 来找到这个单点 \(k\) 次内的操作。基于此有时间轴分块做法,每次插入直接给连续段插入,根号重构。反转操作则更新连续段信息,删除操作对于当前重构块内的可以暴力删除,否则打标记。查询时从后往前找出当前点在哪个连通块,然后从前往后找到第一个插入操作,可以做到 \(O(n \sqrt n \log n)\)。
观察到这个信息支持有结合律的复合运算 \(G_0 \circ G_1 \to G'\)。考虑直接对时间轴建线段树维护,每个长度为 \(L\) 的节点维护这 \(L\) 个信息。首先信息的总大小是 \(O(q \log q)\) 的,由于有强制在线,我们每次会需要支持新加入一个叶子,可以在一个节点全部被填满在对它维护信息,这样复杂度就是对的。
那么加入操作或者反转操作就通过这个操作复合解决掉了。考虑怎么查询,一次查询会在线段树上拉出来 \(O(\log q)\) 个节点,考虑从前往后算,注意到我们只需要维护一个连续段在这段时间有没有被加入,这个可以顺带跟前面的信息一起维护,容易线段树二分做到 \(O(q \log^2 q)\)。
接下来考虑删除操作,考虑我们维护的信息是一个连续段是否有插入操作,其实是两个儿子对应的连续段的信息或起来,因此一个节点的信息被删掉当且仅当两个儿子都被删了。所以我们找到删除操作对应的节点,不停跳父亲,跳到某个点存在一个儿子为之。这样复杂度均摊删除了 \(O(q \log q)\) 次。总时间复杂度 \(O(q \log^2 q)\)。
P9394 白鹭兰
考虑 \(k=1\) 实际上就是判断是否有双极定向方案。扩展一下,等价于把所有点压成集合之后,缩点之后呈现一条链的形状。建出圆方树,也就是说,答案就是删掉一条链上的所有方点,剩下的所有子树的最大值。
考虑 dp,由于一个点向下走肯定会走最大的子树,设 \(f_{u}\) 代表子树 \(u\),向下走一条链的答案的最小值,在合并的时候算答案即可。答案算完了需要跑双极定向。时间复杂度 \(O(n+m)\)。
P6658 边三连通分量
考虑边三换句话说就是两个点删掉任意两条边仍然连通。考虑 P14164 的做法,把边分为树边和非树边。首先考虑给每条树边赋权 \(2^i\),非树边的权值为覆盖的所有树边的权值异或和,我们去讨论这两条边:
- 选一条没有被覆盖的树边:直接把这条边断开。
- 选一条恰好被覆盖过一次的树边和覆盖它的非树边:也可以直接把这条边断开。
- 选两条覆盖它们非树边相等的树边:这会把所有树边划分为若干个等价类,每个 \(\ge 2\) 等价类内部的树边都需要断开。直接异或哈希即可。
不过这个题不能直接断边,需要打标记划分等价类,复杂度 \(O(n +m)\)。
P8970 宿命 | Regulation of Destiny
考虑对距离状压 \(r\) 位来维护覆盖的情况,具体来说,设 \(f_{u,S,T}\) 代表子树内被覆盖的距离的集合为 \(S\),子树外被覆盖的距离集合为 \(T\)。考虑转移,转移分为向上面跳一步,合并兄弟节点,以及选择当前点。
向上走一步和选择当前点的转移都是简单的,这部分复杂度是 \(O(nr4^r)\)。
接着考虑合并子树(这里合并父亲和儿子向上走一步的值,也就是合并兄弟),对每一位(这里的每一位是指上下合起来的状态)分开考虑转移。记 \((a,b),(c,d)\) 为这一位两个兄弟在下方和上方的答案,那么复合起来显然有 \((a,b) \circ (c,d) =((a \vee d) \wedge (b \vee c),b \vee d)\)。
直接做 dp 复杂度就是 \(O(n16^r)\),难以通过。
如果你做过 P10717,大概会马上反应过来这东西可以用一个类 FWT 的东西优化转移的复杂度。现在的问题是,这个东西是最优化,不能做容斥,所以考虑放宽 dp 状态中的限制来利用最优化。那么考虑把 \(f_{u,S,T}\) 的状态重定义为:考虑 \(u\) 子树内被覆盖的集合是 \(S\) 的超集,子树外被覆盖的集合是 \(T\) 的超集。那么有状态预处理转移 \((1,0),(0,1),(1,1) \to (0,0);(1,1) \to (0,1),(1,0)\),发现只有 \(7\) 种不同的转移:
- \((0,0) \circ (0,0) \to (0,0)\)。
- \((0,0) \circ(0,1) \to (0, 1), (0, 1) \circ (0,0) \to (0,1)\)。
- \((1,0) \circ (1, 0) \to (1,0)\)。
- \((1,1) \circ(0,0) \to (1,1), (0, 0) \circ(1,1) \to (1,1), (0, 1) \circ(0, 1) \to (1, 1)\)。
总时间复杂度 \(O(n (7^r+r4^r))\)。这个时限非常操蛋,像是对着 std 开的时限,写的时候需要注意细节,比如压 \(14\) 位还是压 \(15\) 位之类的,卡卡细节卡卡常数多交两发就能过。
宿雾若水遥(mizue)
先考虑根号做法。首先我们考虑如何快速求出一个 \(w(l,r)\),这东西感觉也没有简单的 polylog 做法。直接考虑对原问题做莫队,现在加入一个右端点 \(r\)。我们把贡献刻画为,首先 \((u_r,v_r)\) 链上之前没有被覆盖的点先贡献 \(r-l\) 次,接着所有在区间 \([l,r]\) 某条链出现过的点再贡献一次。
考虑怎么求 \(w(l,r)\),扫描线然后颜色段均摊,每次加入 \(r\) 就给路径覆盖 \(r\),查询就是查有多少个点 \(\ge l\)。基于这个想法,我们扫描线维护历史和即可把这个题做到 \(O(nk \log^2 n + qk \log n)\)。
QOJ6874 Leshphon
- 如何用 \(O(n)\) 条边刻画强连通?
\(n\) 个点强连通和 \(1\) 能到达 \(n\) 个点并且 \(n\) 个点都能到达 \(1\) 等价,直接跑生成树然后从 \(n\) 条边里面搜,复杂度 \(O(n^{k+2})\),bitset 可以优化一个 \(\omega = 64\)。
P10698 [SNCPC2024] 最大流
最大流直接做肯定是难以刻画的,但是最大流是边不相交路径,考虑 LGV 引理。把每条边看作点,尝试 套 LGV,随机给每条边赋权,那么答案就是矩阵的线性基大小。
回忆一下 LGV 引理(主要是我忘了):
对于一张 DAG,记 \(A_{1 \sim n},B_{1 \sim n}\) 分别是 \(n\) 条不交路径的起点和终点,\(\omega(P)\) 为 \(P\) 路径上边权积,\(e(i,j)\) 为 \(i\) 到 \(j\) 的所有路径的 \(\omega(P)\) 之和。记 \(\sigma(P_i)\) 是路径组 \(P_i\) 的一个排列,\(t(\sigma)\) 为排列 \(\sigma\) 的逆序对个数。定义 \(M\) 为:
\[M=\begin{pmatrix} e(A_1,B_1) & e(A_1,B_2) & \dots & e(A_1,B_n)\\ e(A_2,B_1) & e(A_2,B_2) & \dots & e(A_2,B_n) \\ \vdots & \vdots & \ddots & \vdots \\ e(A_n,B_1) & e(A_n,B_2) & \dots & e(A_n,B_n) \end{pmatrix} \]\[\det(M) = \sum_P (-1)^{t(\sigma(P))} \prod_i \omega(P_i) \]
首先考虑如何选出来 \(k\) 个起点和终点,从源点 \(s\) 连边到 \(k\) 个虚点 \(p_{1 \sim k}\),每个虚点又向 \(1\) 的所有出边连边。现在的问题是边的条数炸了,一个想法是对于每个点都建 \(k\) 个虚点,这样可以把边数控制在 \(O(km)\),但是这样点数达到了 \(O(kn)\)。
考虑将 \(M\) 矩阵的每列缩成一个向量,然后把 \(M\) 矩阵看作一个向量组,具体说,定义 \(v(e) = (M_{e_1,e},M_{e_2,e},...,M_{e_k,e})\)。考虑这个向量组是怎么在点与点之间传递的。发现是从 \(u\) 的入边 \(e_1\) 传递到 \(u\) 的出边 \(e_2\)。
考虑这个传递过程可以看作是 \(e_1 \to u \to e_2\),因此我们对 \(u\) 维护所有入边的向量组成的线性基,然后再将线性基的信息传递给 \(e_2\)。因为这个线性基大小最多为 \(k\),所以复杂度是 \(O((n+m)k^2)\)。
P6624 [省选联考 2020 A 卷] 作业题
首先考虑对最外层容斥,枚举 \(i\) 钦定它是 \(\text{gcd}\),记答案是 \(f_i\),求出 \(f\) 容斥一下就可以得到答案。
首先一个重要的观察是,由于 \(m\) 条边总共有 \(m \sqrt V\) 个因子。一个数要成为答案至少需要 \(n-1\) 条边,所以只有 \(O(\frac{m \sqrt V}{n}) = O(n \sqrt V)\) 个 \(f_i\) 不为 \(0\)。接下来考虑如何求 \(f_i\):
首先一个暴力的做法是对于每条边算钦定方案数,这样复杂度十分爆炸,考虑魔改矩阵树定理,具体来说,考虑把边权设为 \(1+w_ix\),那么最后答案就是一次项的系数。总时间复杂度 \(O(n^4 \sqrt V)\)。
P5406 [THUPC 2019] 找树
生成树考虑矩阵树定理,想办法给矩阵树定理魔改一下。原来矩阵树定理对构成环的运算都有效!
放弃最优化,考虑算出哪些权值方案数 \(\ge 1\)。我们给边权为 \(k\) 的边,定义形式幂级数 \(F_k(x) = \sum [i=k]x_i\),由于形式幂级数加法满足交换律,卷积满足结合律,可以直接套矩阵树定理,最后看每项权值和的系数是否为 \(0\) 即可。
题目给的 \(\oplus\) 是位运算,可以做 FWT 和 IFWT,由于 FWT 是线性的,我们先给矩阵每个位置都 FWT 变换一下,问题变为维护数组的点值乘法做行列式,由于每一个二进制数是独立的,对每一个二进制数分开跑行列式即可,复杂度 \(O(n^3 2^w)\)。
P12777 理解 加强版
考虑刻画决策的过程,一次决策肯定以某种顺序遍历子树内的一些关键点,回溯的时候会清掉所有标记点,然后多次重复这个过程做完这个子树。考虑到标记点一定互相有祖先后代关系,否则可以先做完一边再去做另外一边,延迟做是不劣的,所以说一个点的所有儿子在某种意义上是独立的。为了更好刻画,我们设 \(f_{u,k}\) 代表 \(u\) 子树,有 \(k\) 个空余点的最小代价,这里空余点指当前剩下的没有用的点的个数。
考虑 dp 合并的过程,对于 \(u\) 所有儿子,有且仅有两种决策,下面讨论任意一个儿子 \(v\):
- 分配给它 \(k-1\) 个点,剩下一个点继续标记在 \(u\) 上面。
- 分配给它 \(k\) 个点,但是需要抹除 \(u\) 自身的标记,问题在于如何复原 \(u\) 的标记,考虑 \(u\) 的标记复原难点在于需要多次复原 \(u\),并且多次复原的方式不一定相同。
基于这个问题,我们给 dp 加一维 \(x\) 代表强制这个子树做 \(x\) 轮从 \(u\) 上面下放下来的决策来提前算贡献,换句话说这个点的 \(u\) 被钦定了 \(x\) 次贡献。重新讨论:
- 分配给它 \(k-1\) 个点,剩下一个点继续标记在 \(u\) 上面:那么此时子树贡献上来的最小值应该是 \(\min_x(f_{v,k-1,x}+xt_v)\)。
- 分配给它 \(k\) 个点:这样的子树所需要决策的次数之和就是 \(u\) 所需要的决策次数。\(u\) 的决策次数一部分来自于 \(u\) 的父亲,一部分来自于 \(u\) 本身,先背包合并起来再取最小值即可。
然后做完了,时间复杂度 \(O(n^2 k)\)。
CF1750G Doping
先枚举 LCP 和 LCP 后面的一个数,然后对上升段个数二项式反演,具体来说是对 \(a_i=a_{i+1}-1\) 的位置个数反演。由于 LCP 以前的个数都是固定的,不妨设前面有 \(a\) 个位置满足条件,后面至多有 \(b\) 个位置满足条件。记 LCP 的位置为 \([1:i]\),那么在前面钦定 \(x\) 个,后面钦定 \(y\) 个的贡献为:
直接做是 \(O(n^4)\) 的,考虑优化。发现枚举 LCP 后一个只有 \(O(1)\) 种本质不同的 \((a,b)\),优化到 \(O(n^3)\)。发现贡献的形式是卷积形式,考虑 GF,也就是说把上面的贡献看作是 \((1+x)^a\) 乘上一个多项式 \(F\)。总贡献肯定为 \(\sum (1+x)^a F_a\) 的形式,用秦九韶可以在 \(O(n^2)\) 时间解决。
QOJ16332. Efficient Express
对每种值 \(x\) 分开考虑,发现只要这个值的第一个数 \(pre\) 和最后一个数 \(suf\) 连通那么必定所有都连通。
那么决策分为三种:用一个前缀,或者一个后缀,或者用跨中点的那个。先把初始就满足要求的所有 \(x\) 排除,那么决策其实只有后两种:
- 选用第 \(k\) 操作的后缀:要求为 \(\exist k, p_k < pre_x,y_k \le x\)。
- 选用第 \(k\) 操作的跨中点:要求为 \(\exist k, p_k \ge pre,x_k \le x, y_k \le x\)。
二维偏序考虑放到平面上去考虑,每个 \(x\) 的坐标为 \((pre_x,a_{pre_x})\),记做一类点,每个 \(k\) 的坐标为 \((p_k,x_k)\),记做二类点。那么一个二类点 \(k\) 能覆盖的一类点就是除开左下角以外的所有区域,并且覆盖的点 \(pre_x=i\) 需要满足 \(y_k \le a_i\)。换句话说,一个一类点有机会被非右上方的二类点覆盖。
考虑存在不好刻画,容斥变成所有。按坐标的第一维升序做 dp。发现一个一类点一列只有一个(最下面的一个)是重要的,因为下面的限制满足了上面必然会满足。然后设 \(f_{i,j,k}\) 代表处理到了横坐标为 \(i\) 的点,纵坐标 \(\le j\) 的点的 \(y\) 值都必须 \(>j\),\([1:i)\) 所有点的 \(y\) 值都 \(>k\) 的容斥系数总和。复杂度 \(O((n+m)k^2)\)。
*remark:事实上只需要枚举 \(\max(x_k,y_k)\),然后可以直接 dp,不需要容斥。
P10008 [集训队互测 2022] Range Minimum Element
对 \(a,b\) 之间建立双射关系,考虑用一个 \(b\) 去生成一个特定的 \(a\),这就是从大到小覆盖区间空位,最后没被覆盖的全部填 \(1\)。
问题是考虑什么样的 \(a_{1\sim n}\) 可以被生成,找到第一个最小值的位置 \(p\),那么 \(p\) 会作为一条分界线完全分开 \([1,p),(p,n]\),对这两个区间继续递归做。分界线的条件是 \([1,p)\) 能够被若干区间并起来表示出来。
把分裂倒过来做合并来 dp,设 \(f_{l,r,x}\) 代表当前处理区间 \([l,r]\),最小值 \(\ge x\) 的答案,时间复杂度 \(O(n^3c)\)。优化对 \(f_{*,*,i}\) 二项式反演,最后算个组合数即可,时间复杂度 \(O(n^4)\)。
砍树(tree)
题意:给定你序列 \(a_{1 \sim n}\),每次选择任意一个正整数 \(x\) 并把每个 \(a_i\) 对 \(x\) 取模,求最后可能得到的本质不同的 \(a'_{1 \sim n}\) 数量,答案对 \(998244353\) 取模,\(1 \le n,a_i \le 10^4\)。
记当前 \(a_i\) 的最大值为 \(a_{\max}\),次大值为 \(a_{\sec}\)。那么当我们选择的模数在 \((a_{\sec},a_{\max}]\) 之间的时候,只会影响最大值的取值,这个时候的最大值有 \(a_{\max} - a_{\sec}\) 种取值。我们注意到,如果对最大值取了一次,模 \(m\) 且 \(m\) 小于最大值自由取值个数,的模运算,那么最大值可以取到 \([0,m)\) 所有值。
对于一个 \(y\) 进行运算能得到哪些数?很明显是 \(\le \left \lfloor \frac{y-1}{2} \right \rfloor\) 的所有数。记这个数为 \(z\),那么 \(x\) 就等于 \(y-z\)。因为 \(y \bmod (y-z)=z\)。
考虑证明选用大于等于一半的模数操作一定不劣,我们想要由模 \(x(x \ge a_{\max} -\left \lfloor\frac{a_{\max}-1}{2} \right \rfloor)\) 的结果到达模 \(y(y \le \left \lfloor \frac{a_{\max}-1}{2} \right \rfloor)\) 的结果。如果 \(2y \ge \frac{a_{\max}}{2}\),那么我们取 \(x=2y\),那么模 \(x\) 之后再模 \(y\) 和直接模 \(y\) 是等价的,否则我们总能取到一个 \(x=ky\),\(k\) 为一个常数。所以这里证明了选用大于等于一半的模数操作一定可以生成所有序列。
进一步发现我们仅需要对每个数操作一次,这意味着我们可以依次对每个数决策,对这个东西设计 dp,我们把所有数按一定顺序排列,然后 dp。思考这个顺序是什么,感觉从大到小会好做一点。由于这个操作大于等于一半,所以放弃模运算,直接做大于等于的减法。
哦,我们发现,把 \(a_i\) 从大到小排序后,记 \(a_1 - a'_{1}=k\),那么对于所有 \(a_i \ge k\),\(a'_{i} = a_i - k\)。那么可以 dp 了,前缀和可以优化到 \(O(n^2)\)。
亦可赛艇(excite)
题意:给定你一棵 \(n\) 个点 \(n-1\) 条边的数,然后会有 \(m\) 个操作,第 \(i\) 个操作形式为 \((a_i,x_i)\) 代表把 \(x_i\) 节点染为 \(a_i\) 色,其中 \(a_i \in \{0,1\}\),只有红色和蓝色,注意一个节点可以同时被染成两种颜色。定义一个染色是合法的当且仅当,所有有颜色的节点构成的虚树上,叶子节点全部为红色。你需要对于 \(i = 1,2,...,m\) 求出最大的区间长度 \(L\),使得按 \([i,i+L)\) 的方案染色后是合法的。对于每个 \(i\) 是独立的,\(1 \le n \le 10^5\)。
考虑从右往左扫描线,我们称一个蓝色节点是合法的当且仅当它有两棵子树都存在红色节点,或者它自身存在红色节点,一个染色合法当且仅当所有蓝色节点都合法。
我们发现,对于一个蓝点 \(i\),可能存在的极大不合法区间只存在三个:
- 记左边第一个位置满足 \([L,i]\) 合法的左端点为 \(L\),显然 \(\le L\) 的都合法,而 \([L+1:i][i:i]\) 区间都不合法。同理有 \(R\)。
- 找到左边第一个红点 \(l\),右边第一个红点 \(r\),如果区间 \([l,r]\) 不合法,那么区间 \([l,r]\) 任意一个子区间都不合法。
那么我们给这些不合法区间看成二维平面上的矩阵做矩形覆盖,以 \(l\) 为横坐标,\(r\) 为纵坐标,那么第 \(l\) 列最上面的点就是 \(l\) 的答案,扫描线即可维护。时间复杂度 \(O(n \log n)\)。
CF2023E Tree of Life
考虑选择一定只会选两个叶子节点。 我们直接大力 dp,设 \(f_{i,j}\) 代表做完子树 \(i\),从子树 \(i\) 向上传递了 \(j\) 条链的最小代价。dp 的第二维是 \(O(n^2)\) 级别的难以接受。考虑给它砍掉。
我们考虑证明,增大一个最小代价,向上传递的链的条数不会变化超过一。反证,感性一下,感觉挺对的。把 \(f_i\) 改为一个 pair,先优先保证最小代价。
考虑儿子怎么合并,肯定可以一个儿子把边伸入另一个儿子的子树,把这个看成连无向边,那么形成完全图就合法了。我们记所有儿子向上上传的链个数为 \(a_{1 \sim m}\),把 \(a_i\) 从大到小排序,那么可以调整出一个方案每个 \(i\) 最多向后面连 \(m-i\) 条边。
等等,不太对,因为我们的 dp 需要优先保证第一维,而两个儿子如果相互连边可以给第一维代价减一,我们考虑给代价减一的优先级是最高的,因此我们优先匹配,然后再去连完全图。
草了,怎么是反悔贪心,先正常把所有需要连边的边给连了(这里看作有向边去连,拼在一起的形式会好做很多),然后考虑额外的两个路径拼一起。考虑两条路径如果在一个点的子树里面拼一起了,可以把它们拆开然后当作两条向上的链,因此贪心正确性非常对,时间复杂度 \(O(n)\)。
CF878E Numbers on the blackboard
考虑到每个数的贡献都是 \(2\) 的幂次,记第 \(i\) 个数的贡献系数是 \(2^{p_i}\)。那么有 \(p_1 = 0,p_i \ge 1,p_i \le p_{i-1}+1\) 作为 \(p_i\) 的合法判定条件。
考虑如何最优化这个东西,因为尽可能要让正数多贡献,所以要么 \(p_i = p_{i-1}+1\),要么 \(p_i = 1\)。
我们从左往右维护每个上升段,每个负数单独看作一个上升段。如果加入一个正数后,这个段可以和前面的段合并且贡献为正则合并。离线询问,扫描线右端点,问题在于一个块会被切割。而后缀显然比整个块优,直接维护就是对的,复杂度 \(O(n \log n)\)。
P13385 [GCJ 2011 Finals] Ace in the Hole
没有长度为三的递减子序列意味着可以划分为两个递增子序列。考虑如果 Bob 查询到了一对 \(i,j\) 满足 \(a_i \ge a_j\),并且 \((\max(i,j),n]\) 有一个还没被看到,那么 Bob 就达不到 \(n\) 次查询。
AT_arc199_c [ARC199C] Circular Tree Embedding
考虑只有一个排列怎么做,只有一个排列其实这个排列是不重要的。没有交点也就是不存在树上的两条边 \((u_0,v_0),(u_1,v_1) \in T\),使得这两条边在数轴上是交叉的。这个条件也就是把所有边对应的区间,放到数轴上两两要么包含要么不交。
因为这 \(n-1\) 条边需要让 \(n\) 条边连通,关于这个我们可以很方便地设计 dp。具体来说,对于一个区间,我们找到与左端点直接连边的位置 \(p\),那么 \([l,p],(p,r]\) 是两个独立的子问题。因此我们记 \(f_{l,r}\) 代表区间 \([l,r]\) 的答案,即可快速做完只有一个排列的问题。
等等我草,怎么是个环,哦可以断环成链,不影响。
接下来考虑多个排列怎么做,排列的信息变得重要了。钦定 \(p_{i,1}=1\),并且对所有排列同步复合使得 \(p_1 = (1,2,...,n)\)。直接套用上面的 dp 是对的,时间复杂度 \(O(n^3 + n^2m)\)。
P8494 [IOI 2022] 最罕见的昆虫
考虑依次加入 \(1 \sim n\),思考我们会得到什么信息,我们先加入所有昆虫并且维护出所有昆虫加入后众数是否改变,我们的目标是想办法找出最大众数所在的所有位置。
考虑从后往前维护,记最后一个改变的位置是 \(p\)。我们考虑把 \((p,n]\) 删掉,这样 \(a_p\) 就成为了唯一众数,然后考虑继续做 \([1,p)\),倒着做,然后每次找到众数的改变点保留,剩下的全部删掉,这样就只有值为 \(a_p\) 的值被保留下来。
我们的分析太过具体化,对找出最小出现次数并没有什么帮助。考虑如何判定最小出现次数是否 \(\ge x\)。这个很简单,按顺序加入所有数,如果 \(>x\) 就弹出。我们先做一次 \(x=1\) 可以找出种类数,那么判定是容易的。这样得到了一个 \(O(n \log n)\) 的做法?
思考这个东西怎么优化,实际上,每次都对所有数判定太浪费,一个 \(x\) 如果继承一个比它小的 \(x'\) 的状态会更划算。这个方向感觉不是很好优化,吗?
咋这么难,每次把二分上界卡紧到 \(\frac{cnt}{c}\),就可以做到 \(3n\) 次。
P12480 [集训队互测 2024] Classical Counting Problem
首先考虑怎么做多项式复杂度,考虑枚举留下来的子树的 \(\min=s\) 和 \(\max=t\) 算带权和,那么删掉的点需要满足权值在 \([1,s) \cup (t,n]\) 之间。一个方案怎么判定合法性?首先保留的树上一圈我们可以找到哪些点是绝对被操作过并且删掉的,如果这些删掉的点都合法,那么一定存在一种操作方法操作到这棵树。树形 dp 容易做到 \(O(n^2) \sim O(n^3)\)。
进一步,我们发现确定 \(s,t\) 后树形态唯一。观察这个带权和有一项是树的大小,我们把 \(size\) 的贡献拆到每个点上面,记 \(P(u,v)\) 代表 \(u \to v\) 的路径,只需要对每个点 \(u\) 求是否 \(P(u,s) \cup P(u,t) \cup P(s,t)\) 中的每个元素都在 \([s,t]\) 之间即可。
由于我们需要同时处理 \(\max\) 和 \(\min\),我们建立树上笛卡尔树,那么建出来大小根树之后,限制可以被我们刻画为,大根树上 \(t\) 是 \(u,s\) 的祖先,小根树上 \(s\) 是 \(u,t\) 的祖先。我们枚举 \(t\) 的值,那么 \(s\) 的所有可能取值就是大根树上 \(t\) 的子树集合交上小根树上 \(t\) 的祖先集合。最大的问题在于我们如何维护 \(u\) 的可能取值。
考虑每次查询,需要遍历所有在 \(t\) 在小根树上到根的链上面的点,查询每个 \(s\) 它的子树和大根树 \(t\) 的子树的交集的大小。在小根树上做树剖,对每条重链算 \(s\) 在这上面的贡献。加入一个点作为 \(u\),只需要对 \(u\) 到根的所有重链贡献即可,在线段树上面维护 \(s\) 的总和,\(u\) 的个数,合法 \((s,u)\) 的个数,对大根树启发式合并可以做到 \(O(n \log^3 n)\)。相当是启发式合并解决了大根树上 \(t\) 是 \(s,u\) 祖先的限制,树剖解决了小根树上 \(s\) 是 \(t\) 祖先的限制,修改解决了小根树上 \(s\) 是 \(u\) 祖先的限制。
P5776 / gym102759C:边双 / 点双 / 强连通可以用耳分解刻画。

浙公网安备 33010602011771号