Atcoder/Codeforces 记录

Atcoder&Codeforces 记录

ABC362

F - Perfect Matching on a Tree

考虑若根节点已确定,其子树内两个点在子树内部匹配的收益一定小于这两个点与另一个子树内点匹配的收益,那么可知所以无脑将一个子树内的点向另一颗中的点连过去即可,注意这样做的前提条件是最大的子树的体积小于 \(\dfrac{n}{2}\),为了保证这一点,找出重心作为根即可。

Codeforces Round 958 (Div. 2)

CF1988D The Omnipotent Monster Killer

结论:最多 \(\log n\) 次取完所有点。

证明:考虑对于一棵树,如何增加一些点使得答案一定多取一次。发现若对于每个点都连出一条边指向一个点权相对于它极大的点,那么一定是先取这些新增的点,再继续取原来的点,这样每次操作会将点的个数翻倍,也就是最多增加 \(\log n\) 轮,那么就可以设 \(f_{i,j}\) 表示点 \(i\) 的子树内,第 \(j\) 轮删掉 \(i\) 的最小代价,暴力枚举儿子的 \(j\) 转移即可。

CF1989E Distance to Different

对于一个点 \(i\),若其成为一个区间的最小值,那么区间的左右端点一定在其左右第一个小于它的数 \(L_i,R_i\) 所构成的开区间之中,\(L_i,R_i\) 可以直接用单调栈求出,然后考虑删掉 \(x\) 号的答案 \(f(x)\),设当前点对 \(f(x)\) 的贡献为 \(c\),分类讨论一下:

  • \(i <L_x\)\(R_x <i\),此时无影响,\(c=a_x(x-L_x)(R_x-x)\)
  • \(L_x < i <x\),此时可选择的区间左端点少了一个,\(c=a_x(x-L_x-1)(R_x-x)\)
  • \(x <i < R_x\),同理,\(c=a_x(x-L_x)(R_x-x-1)\)
  • \(i=L_x\),此时设左面第二个小于 \(a_x\) 的数为 \(L_2\),那么区间左端点范围变成了 \([L_2,x]\),少了一个 \(L_x\)\(c=a_x(x-L_2-1)(R_x-x)\)
  • \(i=R_x\),同理可得 \(c=a_x(x-L_x)(R_2-x-1)\)

对于前三类,操作为对一个区间的 \(f\) 加上 \(c\),差分维护。对于后两类,枚举 \(i\),用二分和 RMQ 即可求出 \(L_2,R_2\)

ABC366

E - Manhattan Multifocal Ellipse

考虑将式子拆为:

\[\sum\limits_{i=1}^n |x - x_i| + \sum\limits_{i=1}^n |y - y_i| \leq D \]

\(bufx_j\) 表示方程 \(\sum\limits_{i=1}^n |x - x_i|=j\) 的解的个数,\(bufy_j\) 表示方程 \(\sum\limits_{i=1}^n |y - y_i|=j\) 的解的个数,则答案为

\[ans = \sum\limits_{i=0}^D \sum\limits_{j=0}^{D-i} bufx_i \times bufy_j \]

显然若两个数组均已求出,这个式子的计算可以用前缀和优化到 \(O(n)\),不用担心 TLE。接下来考虑如何求出这两个数组。

首先,将 \(x\)\(y\) 数组分别升序排序。以下的下标均为排序后的下标。

显然,能成为解的 \(x\) 的范围为 \(x_1 - d - 1 < x < x_n+d+1\),数据范围告诉我们这个区间内的数不会超过 \(4e6\) 个,我们可以暴力从小到大枚举每个 \(x\),设式子的取值为 \(sum\),同时维护一个 \(pos\),表示当前有几个 \(x_i\) 满足 \(x_i \leq x\)。当 \(x \rightarrow x+1\) 时,\(sum \rightarrow sum + pos - (n-pos)\),这样就能在 \(O(n)\) 的时间内求出 \(bufx\)\(bufy\) 同理。

F - Maximum Composition

考虑对于 \(f_i,f_j\),若

\[f_i(f_j(x)) > f_j(f_i(x)) \]

\[a_i(a_jx + b_j) +b_i > a_j(a_ix +b_i)+b_j \]

移项后最终可以变形为

\[(a_i-1)b_j > (a_j-1)b_i \]

也就是说,若 \(i,j\)满足上式,那么若同时选择 \(f_i,f_j\)\(f_i\) 一定嵌套在 \(f_j\) 之外。以此为根据排序之后,问题转化为依次选取 \(k\)\(f_i\),使得最终结果最大,这就可以很容易的用 DP 解决了。

ABC367

ABC 做的很顺利。然后就是疯狂降智。D 想到同余但是没有想到最优实现方式,想动态维护同余系内的标准值,结果细节死掉了。E 倍增很好想,但是直接想到了更难写但是显然的建图找环,时间不够所以没有写。F 是很简单的小 trick,三次方和判断同构。侥幸没挂大分。仍需要增强思维的敏捷性,避免一条路走到黑,同时改善心态,不能出现节奏大乱的情况。

D - Pedometer

首先破环为链。如果两个点距离为 \(m\) 的倍数,那么 \(s_i\) 一定与 \(s_j\) 同余。动态维护桶即可。

E - Permute K times

倍增板子....

F - Rearrange Query

正解考虑 hash。我们将区间内出现的所有数从小到大排序之后将它们的出现次数按照此顺序拼接为一个字符串,由于每个数对应的位已经确定了,就可以进行 hash 了。

ABC369

没什么好说的。E 调试时间过长以及手速慢导致没打完 F。

G - As far as possible

很显然若选出的点集确定了,建出的虚树上的边权和的二倍即为答案。进一步,新增一个点时,其贡献为它到根节点与其他已经选过的点到根的路径的无交集部分的和。每次贪心的选出这个贡献最大的点即可。此时换掉任何一个叶子都会使得答案不优,考虑维护每个点的贡献,发现删除一条边等价于子树加,直接使用 dfs 序维护即可。

posted @ 2022-08-15 21:20  Aurora_Borealis  阅读(72)  评论(3编辑  收藏  举报