1249D1 - Too Many Segments (easy version)
1249D2 - Too Many Segments (hard version)
题意:给n条平行线段,区间被线段覆盖,问:使所有点上最多有k次覆盖,最少需要删除多少条边。
贪心的思路:从最左(点1)向右找当一个点被覆盖超过k,找到覆盖它的线段,删除右端点最远的线段,如果还超过k,再继续删除。
easy版本一共只有200个点,用差分再求前缀得到点上被覆盖线段的数量,每到一个点遍历所有的边以找到要删除的边。删除这条边后还要在数组l-r中删除1。
hard版本有 2 e 5 2e5 2e5个点,不能直接遍历。但我们仍需要找到覆盖到某一点的边,和点当前的覆盖次数。预存储每个点以它为起始点的边号,和到它就结束的边边号(比如一条直线是(2,5),我们需要在2点存下这条边,再在6点存下,打上标记区分,题中有(2,2)的这种边,所以加入我们在点2存表示开始和结束的不能达到我们接下来要的效果)。不过依然从最左边点开始,将以该点为起始点的边加入到 s e t < i n t > s e g t set<int> segt set<int>segt中,在删除以它为结束点的边(边(2,3),在点4时把他删除,这就是为什么这样存的作用了)(保证segt中的边都是覆盖这个点的),以及一个变量subcur,和一个数组sub。当我们删除一条边(l,r)时,subcur++,sub[r+1] − − -- −−,前缀数组 − - −subcur就可以表示点的覆盖次数。sub数组的作用是维护subcur,当(l,r)线段被删除后,只有l-r的覆盖改变,所有到遍历到r+1点时,需要subcur+sub[r+1]。
hard版本
#include<iostream>
#include<stdio.h>
#include<algorithm>