[IOI2015]teams分组(二维数点+单调栈)

首先可以得到一个\(O((S+n)\log_2n)\)的贪心做法。

考虑到相同的\(K_i\)可以合并在一起询问,因为\(\sum K_i \leq n\)所以不同的\(K_i\)只有\(\sqrt n\)个,
然后对于两个人\([l_i,r_i],[l_j,r_j]\)如果\(l_i,l_j \in [K_i, K_{i+1})\)\(r_i,r_j \in [K_i, K_{i+1})\),那么这两个人对于这一次询问是没有区别的。
这样压缩后,结合上述贪心,复杂度\(O(s\sqrt n \log_2 n)\)
正解是考虑直接优化贪心:
把人看成坐标\((l_i,r_i)\)的点,
那么对于一个\(K_i\),它可以选的点,就是以点\((K_i,K_i)\)为右下角的矩形。
我们先给\(K_i\)按从小到大扫描线。
\(h_i\)表示扫描到\(K_i\),最优方案下,在\((K_{i-1},K_i]\)最小的\(y\)没被选的高度,
\(f_i\)表示剩下多少个没选。
考虑加进一个\(K\),考虑\(h_i<K\)那么这个\(K\)能选的,\(K_i\)一定选不到。
我们搞一个单调栈,维护下降的\(h_i\),这时,我们就弹掉它。
如果\(K>=h_i\),我们可以通过二维数据结构,求出可选的点数目。
然后我们要确定这个\(K\)\(h\)值。
考虑先填满自己,如果超出\(h[top]\)那么这个\(top\)再怎么样也会小于当前的\(h\),我们把它们两个合并。
这样就的到了一个\(O(s\log_2n+n\log_2n)\)的算法。

posted @ 2020-11-18 16:11  zzy2005  阅读(198)  评论(0编辑  收藏  举报