ARC230

AtCoder Regular Contest++ 230

闲话

早上打了代码源,鉴定为三个*1900加一个典题拆贡献。

结果被卡哈希了,双模经典模数被卡,针魔会试呢,出题人疑似有点不要冯冯了。

随机两个模数过了之后就开始睡,一直到晚上 18:30 左右,起来不饿随机搞点whk的水题就开了。

观察发现 AB 明显比较可做,其中 B 是构造所以尤为可做,C 是奇怪的东西,看上去是传统但思维量不小的计数,D 要么是神仙计数要么是科技,事后证明这两个都沾了。E 看着不像人做的题,我翻译插件挂了看不明白它在说啥。

先开 B,注意到等价于 \(A_i\) 可以向一个前缀内的 \(X_i\) 或 \(Y_i\) 连边,并且交替走 \(X_i,Y_j\) 是没有意义的,肯定是存在一个分界点然后两段走自己的。因此可以直接贪心地维护每个位置对应的值域可达区间,那直接贪心地扩展,每次消掉一轮对应的所有位置就是 \(\mathcal{O}(n^3)\),22 min 取得首杀。

此时无疑是高兴的,但是结合 ARC221 的教训我还是得冷静一下,向 codwarm 姐姐询问得知 A 很可做,我先拆的边贡献,对一侧的带权子树记为 \(S\),做类似于 \(\min(|S|, |V(G) \setminus S|)\) 的拆分,发现其实只和子树大小相关并且相邻两项的差很好维护,所以直接维护这个就可以做到 \(\mathcal{O}(n)\),此时 55min 左右。赛后 codwarm 用范德蒙德卷积做到了任意子树大小 \(\mathcal{O}(1)\) 求,我提议把 \(n\) 开到 \(10^{12}\) 然后连边规律换成 Grundy-coloring,疑似有点过于魔怔了。

然后开始看 C,10min 一点思路也没有立刻换 D,注意到可以定一个值域上的分界点 \(v\),然后限制条件等价于存在一行的 \(\max\) 不超过 \(v\) 并且存在一列的 \(\min\) 不小于 \(v\)。这个显然可以容斥,然后两次容斥可以合并到一起,这个时候就卡住了,不知道如何把 \(M\) 的限制扔掉。过了好久突然意识到这个是一个 \(H \times W - 1\) 次的多项式所以可以直接视 \(M\) 与 \(H \times W\) 同阶然后拉格朗日插值。貌似需要用那个分母阶乘形式的优化做到线性。整个逻辑是相当清晰的,写完没怎么调就过了。

因为此时 E 只过了 \(0\) 人,实际上完赛也只有 \(1\) 人通过,所以再回头看 C,注意到可以用笛卡尔树来刻画最值关系和可达性,但是问题变成了要对部分节点缺失的树算拓扑序什么的,这个直到比赛结束也不会。

赛后补了意识到其实就是结合栈来建立笛卡尔树的过程,对着每次合并完之后剩余的那个不确定的子树做类似于总拓扑序计数的操作,学到了。


A

tag:树的重心、组合计数、*1900。

问题等价于,等概率随机给每个点赋权值 \(0/1\),求带权意义下树的重心到其他所有点的距离之和。

考虑每条边的贡献,换言之就是它被跨过多少次。设左子树有 \(i\) 个权值为 \(1\) 的点,右子树有 \(j\) 个,那么这条边的代价就是 \(\min(i,j)\),调整法不难证明必要性,充分性考虑给每条边定序那么邻项交换不难得出这样构造必定有解且解是唯一或唯二的。

则可以直接计算每条边对所有集合产生的贡献,固定边 \((u,v)\),设两端顶点集合分别为 \(A,B\),其中 \(|A| = s, |B| = n - s\) 那么它的贡献就是 \(\sum_{S \subseteq V(T)} \min(|S \cap A|, |S \cap B|)\)。这个 \(\min\) 有很多种处理方式,我的思路是拆成 \(\min(|S \cap A|, |S \cap B|) = |S \cap A| - \max(0, |S \cap A| - |S \cap B|)\)。因为每个点恰好出现在 \(2^{n - 1}\) 个集合内所以贡献是 \(\sum_{S \subseteq V(T)} |S \cap A| = s \times 2^{n - 1}\),对后面那个项考虑将 \(A\) 的状态取反得到 \(S\) 内不在 \(B\) 对应子树的点数,设 \(T = (A \setminus S) \cup (B \cap S)\),那么有 \(t = |T| = s - |S \cap A| + |S \cap B|\),因此这部分有 \(\sum_{S \subseteq V(T)} \max(|S \cap A| - |S \cap B|) = \sum_{t = 0}^{s - 1} (s - t) \times \binom{n}{t}\)。

于是乎整个权值已经被我们解出来了,对固定的边他就是 \(s \times 2^{n - 1} - \sum_{t = 0}^{s - 1} (s - t) \times \binom{n}{t}\)。这个式子直接算是不好处理的,要考虑不同上标的组合数前缀和什么,但是注意到相邻两项之差是容易算的,即为 \(2^{n - 1} - \sum_{t = 0} ^ {s} \binom{n}{t}\),所以可以直接递推维护出所有子树大小对应的贡献,然后统计实际出现的子树大小及其对应的贡献之和。时间复杂度 \(\mathcal{O}(n)\)。

ac link


B

tag:贪心、构造、Ad-hoc、*2600

正着考虑相当于,每个位置从 \(A_i\) 开始,每次向一个前缀对应的 \(X_i\) 或者 \(Y_j\) 连边,问如何在 \(2n\) 步以内走到 \(B_i\),这个相当难想,但是倒着考虑的话,问题就变成了维护每个位置值域上的可达区间 \([L_i,R_i]\) 然后看它什么时刻第一次包含 \(A_i\)。

考虑在 \([l,r]\) 上执行 chmax 操作,令 \(x = X_{r - l + 1}\),对位置 \(i\) 我们要求的是操作前 \(A_i\) 满足 \(L_i \leq \max(A_i, x) \leq R_i\),因为如果 \(x \gt R_i\) 那么不存在合法的 \(A_i\),如果 \(x \lt L_i\) 那么合法区间仍为 \([L_i,R_i]\) 不改变,如果 \(L_i \leq x \leq R_i\) 那么区间会变为 \([1, R_i]\)。因此该逆操作合法当且仅当 \(x \leq \min\limits_{l \leq i \leq r} R_i\)。合法的时候区间内所有满足 \(L_i \leq x\) 的位置对应左边界均可以取到 \(1\)。

同理,对于 chmin 操作,令 \(y = Y_{r - l + 1}\) 那么逆操作合法当且仅当 \(y \geq \max\limits_{l \leq i \leq r} L_i\)。合法时所有区间内满足 \(R_i \geq y\) 对应的右边界可以取到 \(n\)。

不难注意到这样每次操作只会扩展原有区间,因此不会出现区间分裂的情况,同时一次操作有效当且仅当它放宽了至少一个位置对应的值域上的合法区间。因此每个上界至多一次操作会被置为 \(n\),同理每个下界至多一次操作会被置为 \(1\),又因为每次操作有效,所以连续地至多执行 \(2n\) 次操作可以取到任意值。

再来考虑为何任意贪心均正确,因为每次操作和逆操作均为双射,所以只要 \(A\) 满足当前区间限制,倒序操作必定得到 \(B\)。因此问题转化为存在一个时刻,无有效逆操作时,整个局面必定无解。设当前区间对应的数组集合为 \(S = \prod_{i = 1}^{n} [L_i, R_i]\),因为区间始终放宽,所以 \(B \in S\) 时刻成立。此时对任意操作 \(f\),其逆 \(f^{-1}\) 要么为空,则此时逆操作不合法。要么等于 \(S\),因为已经没有能放宽区间的有效逆操作。

那么假设 \(A \notin S\),却存在操作序列可以使得 \(A\) 变为 \(B\),操作序列中必定有一步从 \(S\) 外进入 \(S\),这与 \(B \in S\) 时刻成立矛盾了,故任意贪心无解时整个局面必定无解。

则只需要维护上述贪心过程,每次固定左端点,对右端点递推求出区间 \(L_i, R_i\) 最小值/最大值,以及 \(L_i \gt 1\) 和 \(R_i \lt n\) 的最小值和最大值即可单次 \(\mathcal{O}(1)\) 判定当前左端点为起始位置的区间是否有效。时间复杂度 \(\mathcal{O}(n^3)\)。

ac link


D

tag:组合计数、容斥原理、拉格朗日插值、*2800。

其实这个题还是很难的,过的人多主要是 CF2048G 和这个本质相同。但如果从独立做出的角度来考虑这个并不简单,特别是你还要考虑正赛出这种题给你搞点 weak pretest 的问题。至少这道题我花的时间是前面 AB 之和还多一点。

考虑固定 \(x = \min\limits_{1 \leq i \leq H} \max\limits_{1 \leq j \leq W} A_{i,j} = \max\limits_{1 \leq j \leq W} \min\limits_{1 \leq i \leq H} A_{i,j}\)。那么问题转化为,存在一行所有元素不超过 \(x\) 并且存在一列所有元素不小于 \(x\)。那么实际上就是要数对于每个 \(x\),有多少个矩阵在值域上存在分界点且分界点恰为 \(x\)。

假设选定 \(r\) 行的元素均不超过 \(x\),对任意一列满足这些行限制的方案数为 \(w_1(r) = x^r \times M^{H - r}\),同时因为行限制对所有列中对应行的元素都生效,所以如果这一列所有元素不小于 \(x\) 那么所有属于选定的 \(r\) 行的位置只能取 \(x\),剩下位置会变成 \(M - x + 1\),因此方案数 \(w_2(r) = (M - x + 1)^{H - r}\)。因为每列独立所以至少有一列所有元素均不小于 \(x\) 的方案数为 \(w_1(r)^{W} - \left(w_1(r) - w_2(r)\right)^{W}\)。因此可以直接二项式反演求出 \(f(x)\) 表示 \(x\) 对应的答案,有:

\[f(x) = \sum_{r=1}^{H} (-1)^{r+1}\binom{H}{r}\left[(x^rM^{H - r})^W - \left(x^rM^{H - r} - (M - x + 1)^{H - r}\right)^{W}\right] \]

然后对拆开后的第一项,可以二项式定理合并掉,也即:

\[\sum_{r=1}^{H} (-1)^{r + 1} \binom{H}{r} (x^rM^{H - r})^W = M^{HW} - (M^W - x^W)^{H} \]

那么实际上只需要算第二项对应的贡献就好了。可以直接预处理 \(M\) 的幂次,每次计算的时候递推 \(x, M - x + 1\) 的幂次,就可以 \(\mathcal{O}(H \log W)\) 地求出一个 \(f(x)\),此时时间复杂度 \(\mathcal{O}(MH \log W)\)。

现在当务之急是把 \(M\) 对应的限制去掉,两个思路,要么是进一步拆贡献,转化对 \(x\) 的计数角度,变成统计一类 \(x\) 在某种矩阵上的贡献之和,但是因为这个类似于鞍点的限制我们难以直接将 \(x\) 按照可以取值的区间转化,每新增一行一列都可以分裂出若干区间,至多会有指数级个等价类,这根本做不了。

另一个就是拉差,视 \(M\) 为常数,考虑 \(f(x)\) 关于 \(x\) 的次数,可以同时对行列容斥,选定 \(r\) 行要求元素不超过 \(x\),选 \(c\) 列要求元素不小于 \(x\),因此 \(f(x)\) 也满足:

\[f(x) = \sum_{r=1}^{H}\sum_{c=1}^{W} (-1)^{r+c} \binom{H}{r} \binom{W}{c} x^{r(W - c)} \times (M - x + 1) ^ {(H - r)c} \times M^{(H - r)(W - c)} \]

因此每一项关于 \(x\) 的系数至多为 \(r(W - c) + (H - r)c = HW - rc - (H - r)(W - c) \leq HW - 1\)。所以 \(f(x)\) 是一个次数不超过 \(HW - 1\) 的多项式。那么可以直接拉插了,求出 \(f(x)\) 前 \(HW\) 项分别对应的前缀和 \(S_1, S_2, \dots, S_{HW}\),则有

\[S_{M} = \sum_{i=0}^{HW} S_i \times \frac{\prod\limits_{0 \leq j \leq HW}(M - j)[j \neq i]}{(-1)^{HW - i} \times i! \times (HW - i)!} \]

则可以预处理出前后缀积和阶乘逆元,做到 \(\mathcal{O}(HW)\) 时间复杂度。总时间复杂度 \(\mathcal{O}(HW \min(H, W) \log \max (H, W))\)。

ac link


posted @ 2026-09-28 00:49  Twistedmind  阅读(4)  评论(0)    收藏  举报