CF765F Souvenirs 题解

简要题意:

给定一个序列,每次查询一个区间差最小的2个数的差。

 

解法1(我个人最喜欢的解法):

考虑莫队。

当一个不太经典的数据结构出现时,如果能离线,那么莫队是最自然的想法。

这个问题具有一个很显然的性质就是,对一个区间排好序后,答案一定是某相邻的两个数带来的,所以我们的莫队大概率离不开维护顺序这个问题。

如果能把顺序很快速的维护出来,我们的答案只需要同步于维护顺序的时候维护即可。

显然的,固定住区间某一段,答案关于区间长度是有单调性的。这提醒我们使用只加入莫队(回滚莫队),每次加入右端后,临时加入左侧短区间,然后更新答案,再撤销左侧短区间。

此时我们就已经做到了 $O(n\sqrt q\log n)$ 的复杂度,但是这显然太卡常了,过不去,考虑优化。

刚刚我们的 log 是因为,我们维护顺序使用了平衡树,这里可以考虑压位trie科技,把log强行压成亚log。

但是仔细回想所学,只删除莫队,是通过链表的方式维护的顺序,而且可以做到 $O(1) $ 的维护顺序,我们刚刚不使用他是因为他是删除,而删除是没法维护答案的。

——“为何不把两者结合呢!”

考虑一个这样的算法:你通过先构造链表,然后清空它,最后再撤销刚刚的行为,做到 O(1) 加入维护顺序。

——“用删除的撤销来实现插入!天才的想法!”

至此核心思想已经初具雏形,具体实现留给读者思考。

参考题解:https://www.luogu.com.cn/blog/namelessgugugu/solution-cf765f (里面讲了莫队的详细实现,O(nsqrt(n)))

 

解法2:

考虑分块。

和莫队一样,读者认真思考就会发现,分块和莫队面临这同样的问题:O(nsqrt(n)logn) -> O(nsqrt(n)) ?

直接粘题解:https://www.luogu.com.cn/blog/Mrsrz/solution-cf765f

浅析核心思想,这里利用归并,去掉了一个 log ,与我们刚刚莫队的做法结合起来思考,我们其实可以发现,预先有序的数组维护顺序,似乎是容易去log的

 

解法3:

极其优秀且富有技巧性的标算。O(nlognlogV),非常优秀。

直接粘题解: https://www.luogu.com.cn/blog/lhm126/solution-cf765f

再附上一个不同于主席树的神奇的实现:https://codeforces.com/contest/765/submission/40982512

(注:把归并排序的过程数组存储下来,每个节点是对应区间的数组,类似划分树)

posted @ 2023-09-28 00:12  皮皮的橙子树  阅读(28)  评论(0编辑  收藏  举报