AGC029

A (sb 0/0)

01 序列逆序对个数。

时间复杂度 O(n)

B (Easy 1/0)

不难证明按照和从大到小匹配并删除即可。

时间复杂度 O(nlogn)

C (Easy 1/4)

二分答案并贪心安排,模拟在字典树上 dfs 的过程即可。

本题主要是代码难写。

时间复杂度 O(nlogn)

D (Easy 1/0)

为什么这个题能放 D。

注意是先手希望操作次数最大,所以先手如果能操作就必须会操作。后手的策略肯定是把先手弄到一个障碍物下面,但是可能因为障碍物遮挡不能每轮都移动。

处理出到每一列 i 的最小值并枚举这一列的障碍物更新答案即可。

时间复杂度 O(w+n)

E (Medium 4/1)

降智了,没想出来!!!

钦定 1 为树的根结点,记 M(u,v) 表示 uv 的路径去掉 u 以后的最大值。如果我们扩展到了一个点 u,我们肯定会扩展到所有的 v,满足 M(u,1)<M(u,v)。所以对于两个点 uv,记它们的 LCA 为 w,则 u 会对 v 产生贡献当且仅当 vu 的子树内,或 M(w,1)<M(w,u)后者与 v 无关。注意到对于一个 u,满足条件的 w 肯定是从 u 开始的一条往上的链,所以 u 会对一个子树内的点产生贡献,可以使用树上差分维护。

至于如何找到 w,考虑 1u 路径上的最大值 x,显然 x 以上是不行的、x 以下可以,问题在于如何判断 x 可不可以,再记录次大值即可判断。

时间复杂度 O(n)

F (Easy 4/3)

考虑每次剥离一片叶子。如果我们从一个集合中选择两个点连边,并钦定其中的一个为叶子,那么我们把这个集合和其他集合内被钦定为叶子的这个点全部删去,就可以转化为一个子问题。发现这条边的另一个点并不重要,我们只需要保证删去叶子时集合内的点数 2 即可。

我们把上面的操作换个形式:有一个 (n1)×n 的棋盘,每个格子内有 0 或者 1,要进行 n1 次操作,每次操作如下:

  • 选择一个为 1 的格子,使得其所在行中 1 的个数 2,然后把以它为中心的十字里的数都变成 0

先不考虑删的顺序,我们找出一组可能的 n1 次操作所选的格子集合。这是一个二分图匹配,如果找不到的话显然无解。设第 i 行选择的格子在第 ai 列,我们按照如下方法构造答案:

  • 维护一个队列,其中只有一个初始元素,为唯一没有被选择的列的编号。
  • 进行 n1 次如下操作:取出队首元素 j 并弹出(如果没有则判定为无解并退出),枚举所有使得第 i 行第 j 列的格子里的数为 1i,如果第 i 行还没有选边的话则钦定第 i 行的边为 (ai,j),然后把 ai 加入队尾。

其实就是把上面的操作倒过来进行。

如果操作能顺利进行的话,最后构造出来的解显然是合法的。现在的问题在于:我们有没有可能把有解的情况误判为无解呢?

答案是否定的。事实上,能够找到一组匹配是不够的,我们容易找到比它更强的有解的必要条件,那就是:对于任意 i 个集合,其并集大小 i+1。可以证明在满足这个条件的情况下一定存在解,即它也是充分条件,所以并不会出现误判的情况。

posted @   Scintilla06  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示