AtCoder Grand Contest 058 简要题解

Problem A Make it Zigzag

  考虑使 1,3,5,7,,2n3 这些位置后三个中的最大值在中间,最后再处理一下最后两个位置就行了。

Code

Problem B Adjacent Chmax

  考虑其实问题相当于一个较大数可以把较小数覆盖掉。

  依次考虑原序列每个数在最终序列中占了多长一段。容易发现只需要满足占的那一段里没有比它大的数就可以。

  然后就是个简单 dp。

Code

Problem C Planar Tree

  差点不会这题,感觉好毒瘤啊。

  如果只有 1, 2 这个题瞎做就好了。

  注意到如果奇数和偶数都能连,就是只有 1, 2 的情况,可是 1, 4 不能连。考虑先把这两个烦人的东西干掉。

  考虑 (1,2)(3,4) 相邻的时候直接连起来,然后分别当做只有一个点 2 或者 3。假如原问题有解且不存在这条边,那么显然这条边可以加上去,然后环上随便删一条边就行了。因此原问题和新问题有解性等价。

  注意到如果有连续两个数是相同的,那么可以在其中 1 个连边的时候,两个一起连。考虑把这两个缩一起。和上面同样的方法证明两个问题有解性等价,只是可以加边的原因略有不同。

  现在问题变成 1 不和 2 相邻,4 不和 3 相邻,相邻的数不同,目标把所有的 1, 4 连到别的点上。可以发现,树上不跨过 4 的 (1,2) 相连会导致至少 1 个 3 不能继续和 4 相连。(如果有跨过 4 的话就考虑这个 (3,4),这样处理下去可能会得到不跨过 2 的 (3,4) 相连,但和这个情形是相似的)这样的情况一定是 (1,3,2),考虑把这个缩成 2,继续这个操作。所以每消去一个 1 就会减少一个 3,每消去一个 4 就会减少一个 2。

  如果不存在 (1,3,2) 也不存 (4,2,3),那么说明不存在 (2,3) 相邻的情况,此时可以得到 4 的数量大于等于 2 的数量, 3 的数量大于等于 1 的数量(等于是因为可能都没有),此时显然不可能。

  相反如果满足 2 的数量加上 3 的数量大于 1 的数量加上 4 的数量,同时 1 的数量大于等于 3 的数量,4 的数量大于等于 2 的数量,因为每次两个数量和同时减少,所以不可能出现不存在 (2,3) 相邻的情形。因此只用处理一下,然后数数量就可以了。

Code

Problem D Yet Another ABC String

  这种题比那种无聊的猜结论题有意思多了。

  朴素容斥的话相当于硬点若干个位置,然后这个位置起始长度为 3 的子串不合法。有重叠的话不好处理,主要因为 3 种字符的数量有限制。

  考虑让硬点的位置后面一定不和它相连。就是 ABC 后面不是 A。相当于就是对每个这样连续的 ABCABCAB 末做一个子集容斥。

  然后就是个简单组合计数。

Code

Problem E Nearer Permutation

  感觉这种题和码农题一样无聊,反正顺着思路做就完了,每步难度不大,就是思考的过程特别长。虽然也有可能是因为我菜。

  考虑怎么找出 z

  首先考虑怎么算 d(x,z),相当于将 x 第一个位置上的数,在 z 中改为 1,第二位置上的数,在 z 中改为 2,然后求 z 的逆序对数。

  这个显然相当于 i 在两个排列中出现的位置构成的有序二元组的逆序对数。

  那么现在有 2 列二元组,每列二元组只知道其中 1 个数,从小到大把 1n 填进去,每次尽可能填较小的数对应的二元组。

  现在问题变成判定把剩下的填进来其中 1 列的逆序对数是否不超过另一列的逆序对数。

  可以发现,只有每对 ixy 中出现的位置构成的有序二元组的逆序对会对差有贡献,并且贡献为 +1 或者 1。(其实这个逆序对其实就是 ix 中出现的位置 pi 的逆序对)如果 pi>pj(i<j) 并且 (pi,?) 被先填上数,那么会产生 +1 的差。(最终需要差小于等于 0)我们下面称违反一个逆序对 (i,j)(i<j,pi>pj) 指先在 (pi,?) 填数。

  因此我们可以至多违反逆序对总数除以 2 向下取整个逆序对。

  然后很容易得到一个明确的求 z 的做法:假设当前在确定第 i 个位置上的数,找尽量小的 j 满足上一条限制,然后填上 (pj,i)

  现在回到原问题。

  现在我们要填 p1,,pn,题目指定了上面做法填 (pi,?) 的顺序。

  当我们填了一个 (pi,?)  且前面有没有填的 (pj,?) 时相当于限制此时能违反的数量小于填 (pj,?) 会违反的数量。考虑每次填的过程,允许违反的数量每次单调不增,后者至多减少 1。所以如果下一次填的位置 (pk,?) 满足 k<i,那么意味着上面这个差是刚好变为 0,所以填完 (pk,?) 后不能再违反任何逆序对。这之后只能每次填 p 最小的没填的位置。

  我们将 pi 分为 4 类:

  • 第一类位置:满足 i=zi
  • 第三类位置:第一个满足 zi>zi+1zi+1
  • 第二类位置:设第三类位置为 zt,那么在 z1,,zt1 中满足 zi>i 的为第二类位置
  • 第四类位置:剩下的

  容易发现对于第一类位置没有限制。如果一个现在要填的位置 pi,之前还有没有填的位置 pj,那么一定满足 pi<pj,否则能违反的限制数一定满足能先填 pj。因此在不考虑第三类位置的情况下,第二类位置的限制在处理出第四类位置的 p 的相对顺序后就已知了。

  我们希望使得逆序对数减去 2 倍被违反的逆序对数为 0 或者 1。我们先考虑这个东西的最小值。注意到每产生一个被违反的逆序对的时候对这个值的贡献为 1

  在不考虑第三类位置的时候,最优方案为第一类位置依次填 n,n1,,第一个第二类位置填能填最大的数(能违反的逆序对数到这里的时候最大值就是这个位置上的限制)剩下按顺序填最小的数。

  注意到你可以连续地把这个值加上 1,所以如果第三类位置在第一个第二类位置的后面就做完了。

  考虑第三类位置在所有第二类位置之前的情形。

  如果第三类位置填上后后面有 x 个数比它小,那么到这个位置的时候允许违反的逆序对数也是 x。第三类位置对于倒数第 i 个被填上的第二类位置有一个限制:这后面至多有 i1 个数比它小(注意求 z 的过程运行到这里的时候允许违反的逆序对数是 x)。此时显然最优的话把第一个第二类位置填能填的最大的,剩下的没填的按顺序填能填的最小的。因此我们只用求一下最大可能的 x 即可。(注意这里所有的第二类位置都对这个第三类位置有限制,因为经过第一个第二类位置后,允许违反的逆序对数是 x 不是 0)。

Code

Problem F Authentic Tree DP

  别催了,在路上了.jpg

  不懂就问,这题是给人做的吗?

  (尝试给题解编一个思路)

  显然你需要给这个式子找一个组合意义。看到 1n 容易想到是选择某个东西。但是这个 枚举的是边。考虑每条边拆出一个新点,向原来的两个点连边。但这样变成了 12n1。考虑给这样每个新点挂 P1 个叶子,这样 n1 个新点的贡献就被消掉了。

  这个式子大概是在算一个概率一样的东西,同时注意到枚举的一定是新点,然后将树分成独立的两部分。如果考虑这样得到一个序列,每次在选择在最前的点,可以为这个过程编一个组合意义:求所有新点在序列中的位置在所有邻居前面的概率。

  问题变成一棵树,给定边的定向,问拓扑序方案数。直接对指向根的有向边容斥做背包就完事了。

Code

posted @   阿波罗2003  阅读(162)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2018-08-22 Codeforces Round #505 (Div 1 + Div 2 Combined) Solution
点击右上角即可分享
微信分享提示