Loading

【杂题乱写】2024.02 #1

Page Views Count

AtCoder-ARC171_D Rolling Hash

区间 \([l,r]\) 的哈希值不为零等价于:

\[h_r-h_{l-1}\times B^{r-l+1}\not\equiv 0\pmod P \]

由于 \(B,P\) 均为质数,且 \(B<P\),所以上式等价于:

\[h_r\times B^{-r}\not\equiv h_{l-1}\times B^{-(l-1)}\pmod P \]

\(f_i=h_i\times B^{-i}\),那么对于任意 \(f\),容易还原出 \(h\),也容易还原出原序列。所以只需要对 \(f\) 的限制考虑,发现每个限制等价于 \(f_i\neq f_j\),那么直接状压就能求出结果。

提交记录:Submission - AtCoder

CodeForces-1929D Sasha and a Walk in the City *1900

任选一个根,考虑在一个点集的 \(\mathrm{LCA}\) 处统计答案。

为了方便,认为不包括的 \(\mathrm{LCA}\) 点集选了虚根 \(0\)。这样一个点集合法当且仅当除了 \(\mathrm{LCA}\) 的节点都在 \(\mathrm{LCA}\) 的同一子树内,否则选两个不同子树的和 \(\mathrm{LCA}\) 就不合法了,同时除了 \(\mathrm{LCA}\) 以外的节点也不能有祖孙关系。

考虑 DP,记 \(f_u\)\(u\) 子树内选若干没有祖孙关系的节点方案数,转移是 \(f_u=\prod_{v\in \mathrm{son}(u)}(f_v+1)\)。统计答案时发现就是 \(\sum_{v\in \mathrm{son}(u)} f_v\),因此就是 \(\sum_{u=1}^n f_u\)

提交记录:Submission - CodeForces

CodeForces-1929E Sasha and the Happy Tree Cutting *2300

明示了对 \(k\) 状压。发现 \(k\) 条路径形成的虚树一定是 \(O(k)\) 规模的,所以本质不同的覆盖集合只有 \(O(k)\) 个,直接离散化然后背包就行了。

提交记录:Submission - CodeForces

CodeForces-1929F Sasha and the Wedding Binary Search Tree *2300

有点水了,直接找到中序遍历,对每个极长未知段求方案数,答案就是关于长度和值域的组合数。

提交记录:Submission - CodeForces

Luogu-P8860 动态图连通性

容易发现每条边只有第一次询问是有用的,记第 \(i\) 条边的边权为首次被询问的时刻,如果从未被询问设成 \(q+i\)

考察所有 \(1\rightarrow n\) 路径中最终留下的是哪一条,只有这条路径上的边不会被删去。首先路径中边权最小的一条,一定是要最小的尽量大,其他都先被删去了,最小的相等的所有路径中再比较次小,以此类推。所以是找所有路径中,升序排序后字典序最大的一条。

可以根据某条边是否出现来用二进制数表示一条路径,其中较小的边权放在较高的位上,所以是求一个高精度最短路,可以用主席树之类的解决,和某道 CodeForces 题类似。

本题具有一个特性:边权互不相同,考虑这个性质能不能指向一个更简单的做法。

假设 \(u_1,u_2\) 均可转移到 \(v\),边权分别为 \(w_1,w_2\),假设 \(d_{u_1}<d_{u_2}\),也就是朴素 Dijkstra 中 \(u_1\) 先弹出。此时应当有 \(dis_{u_1}+w_1>dis_{u_2}\),否则 \(v\)\(u_2\) 先弹出,转移没有意义。观察 \(dis_{u_1}+w_1,dis_{u_1},dis_{u_2}\) 的二进制位,应当是有一个前缀相等,不相等的位置一定对应 \(w_1\),所以 \(dis_{u_1}+w_1\) 这一位是 \(1\)\(dis_{u_1}\) 这一位是 \(0\),而 \(dis_{u_2}\) 一定没有走 \(w_1\) 这条边,所以这一位也是 \(0\),进而可以知道后面一定是 \(dis_{u_2}\) 的更大。

那么如果 \(w_2<w_1\),就会加在更高位,一定不优,如果 \(w_2>w_1\),这个 \(w_2\) 一定不会产生进位,一定更优。所以转移实际只取边权最大的一个即可。

提交记录:Submission - Luogu

Luogu-P6845 CEOI 2019 Dynamic Diameter

考虑用欧拉序来描述 \((u,v)\)\(\mathrm{LCA}\)。记 \(p_u\)\(u\) 第一次出现的位置,\(d_i\) 为欧拉序 \(i\) 对应节点的根链长度,那么 \(\mathrm{dist}(u,v)=d_{p_u}+d_{p_v}-2\min_{i=p_u}^{p_v} \{d_i\}\)。由于减去区间的 \(\min\) 等价于枚举区间内任意元素取 \(\max\),而要求的直径就是所有路径长度取 \(\max\),所以原题要求:\(\max_{x\le z\le y}\{d_x+d_y-2d_z\}\)

容易用线段树维护区间信息,修改边权实际是对欧拉序区间的 \(d\) 进行修改。


另一种做法的第一步是比较容易想到的——线段树维护区间直径。合并两个区间是经典性质。带修看起来不好处理,但实际上只会影响同时包含 \(v\) 子树内外节点的区间,所以直接在线段树上重新递归 \(v\) 子树对应的 DFS 序区间就行了。

提交记录:Submission - Luogu

CodeForces-1930C Lexicographically Largest

\(c_i\) 表示在取走 \(i\) 取走的位置 \(<i\) 的元素个数,容易发现对于任意 \(0\le c_i<i\),这样的 \(c\) 都是合法的,证明考虑归纳,每次前 \(n-1\) 的元素的相对顺序不变,在操作序列的第 \(c_n+1\) 位置插入 \(n\) 即可。

也就是能构造出 \(b_i\in [a_i+1,a_i+i]\) 的任意结果,容易发现集合中有重复元素一定不优。所以维护若干区间 \([l_i,r_i]\),初始是 \([a_i+1,a_i+i]\),每次取出右端点最大的中左端点最大的一个,将右端点加入答案集合,其余的右端点同样的最大的右端点减一。

提交记录:Submission - CodeForces

CodeForces-1930D1 Sum over all Substrings (Easy Version)

注意到一个 \(\texttt{1}\) 可以使左中右三个位置的 \(\texttt{1}\) 合法,即中间选自己,左右选长度为 \(2\) 包括中间的区间。由于每三个位置只会出现一个 \(\texttt{1}\)\(\texttt{0}\) 的条件自然也满足了。

只需要固定左端点拓展一个右端点算答案就行了。

提交记录:Submission - CodeForces

CodeForces-1930D2 Sum over all Substrings (Hard Version)

考虑把 D1 的枚举左端点移动右端点改成批量算。

\(f_i\) 为以 \(i\) 开头所有区间的答案,从大到小枚举 \(i\) DP。

如果 \(s_i\)\(\texttt{0}\),那么直接 \(f_i=f_{i+1}\)

如果 \(s_i\)\(\texttt{1}\),放置一个 \(\texttt{1}\) 可以直接把 \([i,i+2]\) 的条件全部满足,于是 \(f_i=f_{i+3}+(n-i+1)\)

答案就是 \(\sum_{i=1}^n f_i\)

提交记录:Submission - CodeForces

CodeForces-1930E 2..3...4.... Wonderful! Wonderful!

一个序列合法的充要条件是:有恰好 \(i\times 2k\) 个位置被删去,且至少存在一个未被删去的位置左右都有 \(k\) 个位置被删去。证明是感性的,可以认为把最后一次操作还原之后的限制更松。

考虑枚举 \(i\times 2k\),不妨减去不合法的情况,此时从左往右第 \(k\) 个被删去的位置和从右往左第 \(k\) 个被删去位置中间应该都被删去,把它们缩成一个,就是有 \(2k-1\) 个位置被删去。所以答案是 \(\binom{n}{i\times 2k}-\binom{n-i\times 2k+2k-1}{2k-1}\)。时间复杂度是调和级数 \(O(n\log n)\)

提交记录:Submission - CodeForces

CodeForces-1930F Maximize the Difference

注意答案可以写成:

\[\max_{1\le i,j\le q,0\le x<n} \{(b_i|x)-(b_j|x)\} \]

对每一位讨论,如果 \(b_i\)\(b_j\) 相同,\(x\) 任取均可;如果 \(b_i\)\(1\)\(b_j\)\(0\)\(x\)\(0\);如果 \(b_i\)\(0\)\(b_j\)\(1\)\(x\)\(1\)。所以实际上是 \(x=b_j\)

观察 \((b_i|b_j)-b_j\) 发现就是 \(b_i\)\(b_j\)\(c_j\) 的交。朴素做法是 \(O(3^{22})\) 枚举子集。

由于只需要找到最大的同时为 \(b\)\(c\) 中元素子集的值,所以每个值实际是标记,直接 BFS 就可以做到 \(O(n\log n+q)\)

posted @ 2024-02-16 11:47  SoyTony  阅读(32)  评论(0编辑  收藏  举报