前言
怎么没有人写官方做法,set
应该比线段树好写吧。
题意
给定长为 n 的序列 a,b,对 k∈[1,n] 求 min{maxi=1kci−mini=1kci,ci=ai∨ci=bi}。
做法
开始也没什么信息,所以可以先钦定 c1=a1∨c1=b1。当 c1 固定后,可以分析出一些结论了。设 ai≤bi,若不是就交换一下,则变成在区间上取两个端点之一。对于 ai≤bi≤c1,显然 ci=bi 是不劣的,同理,c1≤ai≤bi,选择 ci=ai 是不劣的。当固定这些 ci 后,又可以固定更多的 cj。形式化的,设 L 为当前固定的 ci 中的最小值,R 为最大值,则满足剩下的 ai<L≤R<bi。
接着考虑剩下的区间,若存在 ai≤aj≤bj≤bi,即存在包含关系时,i 所形成的极差一定不会比 j 的更小,所以 j 必然不会贡献答案,可以删除 j。
将最后剩下的区间设为 l1≤⋯≤lm≤L≤R≤r1≤⋯≤rm,则答案为 min{mini=1m−1(ri−li+1),L−l1,rm−R}。
开一个 set
维护 [li,ri] 和一个 multiset
维护 (ri−li+1)。每次插入一个区间 [ai,bi] 时先检查 set
中是否存在 [lj,rj] 包含了 [ai,bi],若有则不用修改,否则再将所有被 [ai,bi] 包含的 [lj,rj] 从 set
中删除,最后类似于链表的插入,将 [ai,bi] 插入到 set
中,同时删除和插入时需要同步更新 multiset
中的答案集合。
由于每个区间只会插入和删除一次,所以时间复杂度为 O(n×log2n)。实际上要跑 1s 左右,STL 常数较大,但比较好写。