Codeforces Round #809 (Div. 2)

VP的。

这场 C 是真的恶心,还好一发过了要不然罚时就更起飞了。

D2

考虑枚举 [l,r],判断能否使得所有 aipi 都在 [l,r] 范围内。

对于每个 ai,aipi 只有 n 种值,所以这个判断可以用一个桶实现。

注意每个 r 能取得的最大 l 随着 r 的增加单调不降。可以 two-pointers。

然而空限 64MB。卡不过去,怎么办?

其实方法很简单,不要把每个 ai 的所有 aipi 一下子全部扔进一个序列里。假设从大到小枚举 r,当目前的 aipi>r 时,再把下一个更小的 aipi>r 纳入考虑范畴。

vp 的时候没写 D1,直接写的 D2,由于 vector 内存释放问题改成了前向星,改了半天,赛后 30s AC,蚌。

然后经高手指点才知道 vec = vector<int>() 就可以释放内存,更蚌埠了。

无知的后果。

E

赛后补的。

我的思路是这样的:依次加入每条边,并查集启发式合并。每个集合的根节点存下当前集合内点构成的所有区间。合并时二分,如果 [l,k][k+1,r] 合并到了一起那么 [l,r] 内的区间的答案就不超过当前边的编号。这个可以线段树维护二维数点(min 不能树状数组),或者更优美的,注意到每次产生的 [l,r] 必然不相交或者完全包含,把它建成一个树形结构,对于每次询问 x,y,求 xy 的 lca 就是答案。复杂度 O(nlog2n)

官方题解说,[l,r] 连通等价于对于 li<rii+1 连通,所以我们记 f(i) 表示最少加入第几条边时 i,i+1 连通,查询等价于一个 rmq。然后这个 f(i) 非常好求,可以并查集启发式合并但是两只 log,还可以将第 i 条边权值设为 i 跑最小生成树,ii+1 路径上的最大边权就是 max。复杂度 O(nlogn)

这个生成树的奇妙结论怎么证呢,如果要从生成树的角度来证明很难证,但是如果从 kruskal 的过程考虑你会发现这不就是并查集合并的过程吗。。。

对比一下简洁程度,代码长度和复杂度,高下立判,技不如人,赛时写不完也只能甘拜下风。更何况我因为 vector 内存释放卡在了D2

这个 [l,r] 连通转为 ii+1 连通是个没见过的 trick,学到了。其实这个 trick 也不局限于连通,有传递性的信息都可以这样搞。

本文作者:zqs2020

本文链接:https://www.cnblogs.com/stinger/p/16574042.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   zqs2020  阅读(41)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.