题意:
有n条线段,每条线段覆盖的点为[li,ri],如果点被超过k条线段覆盖,那么这个点为坏点,
问,最少去掉哪几条线段,可以使得没有坏点?
思路:
点从左往右扫,如果这个点为坏点,那么就去掉一些 覆盖这个点的线段,从ri最大的开始删,不需要考虑li是因为你已经保证左边没有坏点了,那么删掉的线段当然是ri越大越好。
用multiset维护当前覆盖这个点的线段是哪几条。
今天才知道,sort的时候,外部定义的cmp函数可以覆盖结构体里的重载运算符'<'。
果然不是大佬就少用stl,测样例的时候RE,交了两发也RE,调好久。
代码:

#include <stdio.h> #include <string.h> #include <cmath> #include <iostream> #include <vector> #include <set> #include <algorithm> using namespace std; typedef long long int ll; const double pi = acos(-1); const int maxn = 2e5 + 10; const int inf = 0x3f3f3f3f; struct node { int l,r,id; friend bool operator <(node x,node y){ return x.r < y.r; } }a[maxn]; bool cmp(node x,node y) { return x.l < y.l; } int vis[maxn]; multiset<node>st; int main() { multiset<node>::iterator it; int n,k,ans,mx; while(scanf("%d%d",&n,&k) != EOF){ ans = 0; mx = 0; st.clear(); memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++){ scanf("%d%d",&a[i].l,&a[i].r); mx = max(mx,a[i].r); a[i].id = i; } sort(a + 1,a + n + 1,cmp); int cnt = 1,now = 0; for(int i = 1;i <= mx;i++){ it = st.begin(); while(it != st.end() && (*it).r < i){ st.erase(it); it = st.begin(); now--; } while(cnt <= n && a[cnt].l <= i){ st.insert(a[cnt]); cnt++; now++; } it = st.end(); while(now > k){ it--; vis[(*it).id] = 1; st.erase(it); it = st.end(); now--; ans++; } } printf("%d ",ans); for(int i = 1;i <= n;i++){ if(vis[i]) printf("%d ",i); } puts(""); } return 0; }