Codeforces 做题记录

Codeforces 做题记录

CF896E:第二分块。离线后每块分别处理。然后直接值域平移合并,通过操作分类后均摊分析保证复杂度。

CF1039D:若已知 \(k\) 存在一个 \(O(N)\) 的贪心,从叶往上开始选。然后根号分治,对于 \(k\le \sqrt N\) 直接贪心,注意到答案有单调性,所以对 \(k>\sqrt N\) 二分答案变化的分界线。

CF850F:考虑枚举最终的颜色,这样我们只需关注颜色 \(c\) 的球数的变化情况。后面推推式子就出来了。

CF360E:诡异图论贪心题。我们有如下观察:对于 \(S_1\) 倾向于走而 \(S_2\) 不倾向于走的点,其出边一定取 \(l\),否则取 \(r\)。换句话说,考虑一条边 \((u,v,l,r)\)。如果 \(dis(S_1,u)<dis(S_2,u)\),那么 \(w\) 一定取 \(l\);如果 \(dis(S_1,u)>dis(S_2,u)\),那么 \(w\) 一定取 \(r\)。如果 \(dis(S_1,u)=dis(S_2,u)\) 怎么办?因为一旦 \(S_1\)\(S_2\) 走到 \(u\) 上就不再分离,所以取 \(l\) 可以促进两点走到 \(u\) 上而达成 DRAW;否之则有可能争取到 WIN 的情况(也可能反而达成了 LOSE,所以先看一下能否取 WIN,再看一下能否取 DRAW)。

CF555E:神秘结论:边双一定可以重定向为 SCC。证明考虑数学归纳。后面就是简单的树上操作了。

CF19D:线段树套 set。按期重构 KDT 能不能过呢

CF1746F:神秘随机化。注意到如果每个出现过的正整数的出现次数都是 \(k\) 的倍数,那么总和一定是 \(k\) 的倍数。给每个权值随机赋个值就可以了。

CF757F:支配树板子。核心思想:支配关系构成树形关系,每个点的支配点为其支配树上的祖先。

CF79D:考虑差分,就是一次翻转两个点。如何翻转任意的两个点?其实就是一个最短路。

CF830D:如果只设 \(f[n]\) 表示深度为 \(n\) 时的答案,你会发现很难维护,因为一条路径可以在上面做一个中转点然后又回到原来下面的子树内。注意到这样实际上在这个子树内形成多条路径;所以设 \(f[n,k]\) 表示深度为 \(n\) 且子树内有 \(k\) 条路径就能转移了。

CF1404E:考虑如何把格子划分为两个集合——被横砖覆盖和被纵砖覆盖。求最大的 连接两个纵砖格的横边数+连接两个横砖格的纵边数。发现贡献在边上很难搞,考虑边点互换,点表示这条边能否贡献,边表示两个命题是否矛盾,答案就是最大独立集,注意到因为可以黑白染色所以是二分图。

CF1592F2:一个简单的观察就是翻转右上角和左下角的操作没有用。一次翻转一个矩阵很棘手,考虑对原矩阵做差分 \(d_{i,j}=a_{i,j}\oplus a_{i,j+1}\oplus a_{i+1,j}\oplus a_{i+1,j+1}\),那么最终矩阵变为 0 当且仅当差分矩阵变为 0。那么左上角操作 \((x,y)\) 只会翻转 \((x,y)\);对于右下角操作 \((x,y)\),会翻转 \((n,n),(n,y-1),(x-1,n),(x-1,y-1)\) 这四个点。注意到这样我们一定不会对于同一行或同一列的两个点使用右下角操作,因为这样劣于 3 次左上角操作,于是构成了行与列的一个匹配。

  • [ ]

CF1477D:首先对于每个点都能直接连接的点无论如何都一定是满足的,我们先把这样的点删掉。如果有一个点满足与一些点没有直接连接,那么一定存在一种定边方式满足可以让这个点跟这些点在拓扑序中相邻。这样,可以安排两种拓扑序让这个点错开,以使得贡献为零。考虑在反图中是什么回事:第一步删掉了孤立点,剩下的若干个连通块的生成树上菊花剖分。

CF1067E:抽象题,一开始用高斯消元的思想推半天。秩=选择最大的行列式非零的子式。行列式又怎么搞呢,考虑用排列逆序对的那个定义,即

\[\det A=\sum_{\pi}\operatorname{sgn}(\pi)\prod_{i=1}^na_{i,\pi_i} \]

易见行列式非零当且仅当存在一个排列 \(\pi\),使得 \((i,\pi_i)\) 的边存在。所以秩=两倍的最大匹配数。后面就是简单的树形DP了...

CF1316F:推式子,权值线段树

CF1491G:置换环,直接构造

CF762F:爆搜剪枝

CF472G:分块+bitset

CF1286C2:不会

  • [ ]

CF838C:首先如果能够删去一个字符到达先手必败状态,那么先手肯定必胜。否则先手必胜当且仅当当前串的排列数是偶数。当前串的排列数 \(\dfrac{n!}{\prod_{i=1}^k c_i}\) 为奇数等价于 \(n\) 在二进制意义下为 \(c\) 的不交并。如果当前串的排列数是偶数那么肯定先手必胜了,否则就满足上面这个苛刻的条件,如果我们找到唯一一个 \(\operatorname{lowbit}(c)\) 最小的那个 \(c\),并删掉他,那么显然仍然满足这个条件;可以这样先后手交换着做直到 \(n=1\),此时先手必胜;由此可见如果当前串的排列数为奇数,则先手必胜当且仅当 \(n\) 为奇数。综上我们需要求出有多少种字符串排列数为奇数,这个就是不交并卷积,FWT 即可。

  • [ ]

CF446D:考虑高斯消元,然后你发现「误差不超过 \(10^4\)」的限制非常好,所以你只需要把每个点的前几元列出来就可以了

CF1137E:只有在下凸包上递减的点是有用的。每次 3 操作在后面弹出

CF1976F:「割边」是唬人的,其实就是在树上选若干简单路径,使被覆盖的边形成一个包括根的连通块,使覆盖的边数尽量多。因为保证根只有一个儿子,第一步肯定是选根到某个叶子的路径,后面则是选某两个叶子的路径。而且在树上任选 \(x\) 个叶子一定存在 \(\left\lceil\dfrac x2\right\rceil\) 条路径覆盖它们形成的虚树。因此 \(k\) 条路径的答案就是要选择 \(2k-1\) 个叶子到根覆盖的点数尽量多。这个容易用长剖+线段树维护的优先队列做到均摊 \(O(n\log n)\)

CF1515G:首先环路一定是在一个强连通分量里的。考虑求出所有经过 \(v\) 的环路的 \(\gcd\),但是可能很多。因为环上可能还会套一个环,从而形成新环。设环 \(A\) 上可以套一个环 \(B\),则答案包括 \(\gcd(A,A+B)\)。注意到它等于 \(\gcd(A,B)\)。所以答案等于该强连通分量中所有简单环的长度的 \(\gcd\)。考虑生成树,每条非树边 \((x,y)\) 的贡献为 \(dis_x-dis_y+w\),这样就做完了。

CF1221E:这种非公平游戏瞪就完了。因为 \(a>b\),所以长度在 \([b,a)\) 之间的串 Bob 能操作而 Alice 不能,因此 Bob 的胜率会比较大。更进一步的,如果存在 \([b,a)\) 的串,那么 Bob 必胜;策略是 Bob 先不操作这些串,而 Alice 也操作不了这些串,如果 Bob 遭遇了困境,就选择操作这些串,这时 Alice 就操作不了了。如果存在 \(\ge 2b\) 的串,那么 Bob 可以在用这样的串制造一个 \([b,a)\) 的串从而获胜。因此如果存在至少两个 \(\ge 2b\) 的串或者只存在一个 \(\ge 2b\) 的串 \(l\) 而且 \(\left\lceil\dfrac{l-a}2\right\rceil\ge 2b\) 那么 Bob 也必胜。如果 Bob 做不到这点,他会尽量消除 \([a,2b)\) 的串,易见无论对于哪个人来说已经消除过的串就不能再选了,因此判断这个东西的奇偶性即可。

CF1630F:大概就是要求删掉 \(A\) 中若干元素,使 \((A',|)\) 的 DAG 由两条反链构成。根据 Dilworth 定理,就是说最长链为 2,也就是形成了若干匹配,除了这些匹配外再无别的边。考虑拆点,表示 \(u\) 为出点或入点,连边表示两种情况矛盾,于是答案就是新图的最大独立集。注意到新图也可以定向为偏序关系,所以求其最长反链亦即最小链覆盖即可。这个是网络流板子。

CF925E:树剖+分块

CF1109F:「树」可以拆成两个条件:m=n-1 和没有环。「没有环」的条件可以用 LCT+双指针解决。m=n-1 呢?考虑在双指针时对于合法的 \(i\in[l,r]\) 实时维护 \([l,i]\) 的边数,可以用线段树维护。

CF961F:注意到如果给一个字符串前后两端各添一个字符,那么 border 最多增加 2。所以你从中心往两边做,用 hash 判断,不合法就减 2 判断,均摊复杂度是对的。

CF1137F:首先可以发现最大的点一定是最后操作的,所有把它当成根节点。一次 up 操作之后,一定是 rt -> x 依次操作,类似“染色”,考虑用 LCT 的 Access 操作模拟。这样每个 LCT 实链表示一个时间连续段,用 BIT 维护时间前缀 size 即可。

CF932G:很智慧的一步:把字符串的后半段翻转过来隔一个插进前半段中。于是转化为偶回文划分方案数。经典的 PAM 题。

CF1916G:不会

CF1163F:删边最短路。考虑先得到一条最短路,然后拿别的边表示最少需要的最短路上的前缀和后缀来在最短路上区间 ckmin 更新。

CF1768F:神仙 DP 题。大概就是这样的 DP

\[f_j=\min\{f_i+\min_{k=i}^j a_k\times(j-i)^2\} \]

注意到 \(a\) 比较小(\(a_i\le n\)),一般情况下一步一步跳是比较优的。如果我们一步从 \(i\) 跳到 \(j\) 而非一步一步跳,就有 \(\min_{k=i}^j a_k\times(j-i)^2<n(j-i)\),所以 \(j-i<n/\min_{k=i}^ja_k\)

我们能否在 \((i,j)\) 中选择一个中转点 \(k\) 呢?容易发现取 \((i,j)\) 中的最小值是最优的,而且如果 \([i,j]\) 的最小值在 \((i,j)\) 中就一定比 \(i\)\(j\) 直接跳要优。因此能从 \(i\) 跳到 \(j\) 还有一个条件就是其最小值要么在 \(i\) 要么在 \(j\)

对于每个 \(j\) 我们找到第一个小于它的位置,在这个位置之前都有 \(\min_{k=i}^ja_k=a_j\),这个位置与 \(i>j-n/a_j\) 的条件取 max,就可以得到可能合法的 \(i\) 的取值区间。看见这个 \(n/\),还有 4e5 的范围很容易想到根号算法。如果 \(a_j>\sqrt n\) 那么这个区间长度 \(O(\sqrt n)\) ;否则 \(a_j\le \sqrt n\),可以证明因为此时 \(a_j\) 比较小,所以到前面第一个小于它的距离也比较短,是均摊 \(O(\sqrt n)\)。总而言之就是把这个取值区间遍历更新一遍就可以了。

对于每个从 \(j\) 开始的严格后缀最小值 \(i\) 同样可能满足条件,对于 \(a_i>\sqrt n\) 最多只有 \(O(\sqrt n)\) 个;对于 \(a_i<\sqrt n\) 因为是严格的 \(a_i\) 互不相同所以同样最多只有 \(O(\sqrt n)\) 个。搞一个栈保存这些数暴力更新即可。

CF765F:小清新 DS 题。莫队+平衡树可以做到 \(O(n\sqrt n\log n)\),但是这是没前途的。考虑扫描线,设当前扫到 \(i\),不是一般性的,先考虑 \(a_j>a_i\) 的情况,\(a_j-a_i\) 何时能够贡献答案?只有后缀最小值有用这一点是肯定的,但是有更强的结论。如果后面已经有了 \(a_{j'}-a_i\) 更新了,那么 \(a_j-a_i<a_{j'}-a_j\),即 \(a_j <(a_i+a_{j'})/2\),因此有用点的个数是 \(O(\log V)\) 个的,直接搜出来更新答案就可以了。

CF1656H:考虑对每个质数 \(p\) 依次分析,如果有一个 \(a\in A\) 使得 它在 \(p\) 上的指数大于 \(\forall b\in B\)\(p\) 上的指数,那么 \(a\) 肯定选不了,直接删掉就可以了;\(B\) 同理。如果我们一直这样删直至删不了,那么一定可以得到一组合法的方案(除非最后得到一个空集)。但是这样太慢了,你发现这样意味着 \(\gcd\{\frac a{\gcd(a,b)}|b\in B\}>1\),所以你搞一个线段树维护这个东西,每次扫一遍不合法就删掉它就可以了。

CF1677E:值域 \(O(n)\) 时看到这种乘法应当警觉。注意到有用的 \((p_i,p_j)\) 对的数量为 \(O(n\log n)\)。所以转化为求矩形内的矩形面积并,扫描线即可。

CF1634F:考虑另类差分 \(a_i'=a_i-a_{i-1}-a_{i-2}\),则可以差分为单点加。判断是否相同可以 \(A-B\) 然后判断是否 \(\min=\max=0\)

CF914F:bitset 匹配字符串。核心思想就是维护当前合法的开头位置。

CF578F:不会

CF506E:不会

CF464E:确实有够经典的。用主席树上哈希维护高精度数字。

CF643F:神叉!考虑信息论。有 \(i\) 天时我们获得的的信息\(\sum_{j=0}^{\min(p,n-1)}\binom nji^j\)。这个上界是可以构造达到的,所以答案 \(R_i\) 就是这个。

CF1305H:不会

CF643E:注意到只需要输出 \(10^{−6}\) 的精度,说明这道题可以乱搞。注意到随机删边的情况下最大深度不会很大,所以考虑设 \(f(u,k)\) 表示以 \(u\) 为根的子树最深深度为 \(k\) 的概率,转移很简单,\(k\le \lg(10^6)\)

CF1458D:考虑前缀 \(1\) 的个数减 \(0\) 的个数,那么一次操作就是在二维平面上把一段始末点高度相同的折线轴对称翻转,于是可以把高度相同的点缩成一个点,然后就是字典序最小的欧拉路径。

posted @ 2025-04-26 21:13  justalearner  阅读(44)  评论(0)    收藏  举报