题意:给定n条线段和覆盖上限k,每条线段都覆盖了区间内的整点
问最少删掉几条线段能使所有的整点都被覆盖不超过k次
k<=n<=2e5,l[i],r[i]<=2e5
思路:比赛时候不会做,当场好多div3小哥做出来,赛后观摩红名大佬的代码觉得强如闪电……
考虑贪心,将线段存到以起点为编号的vector中
扫描左端点,每次将当前vector的所有线段加入
考虑当前端点被覆盖超过k次,每次必定是选终点最大的线段删除
用set存线段,模拟这个过程,当左端点左移之后还要把右端点已经过了扫描线的线段删除
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 //typedef pair<ll,ll>P; 11 #define N 300010 12 #define M 2000010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pb push_back 17 #define pi acos(-1) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 21 #define lowbit(x) x&(-x) 22 #define Rand (rand()*(1<<16)+rand()) 23 #define id(x) ((x)<=B?(x):m-n/(x)+1) 24 #define ls p<<1 25 #define rs p<<1|1 26 27 const ll MOD=1e9+7,inv2=(MOD+1)/2; 28 double eps=1e-6; 29 int INF=1e9; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 VII c[N]; 34 int ans[N]; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 46 47 int main() 48 { 49 int n=read(),k=read(); 50 rep(i,1,n) 51 { 52 int x=read(),y=read(); 53 c[x].pb(MP(y,i)); 54 } 55 set<PII>S; 56 int m=0; 57 rep(i,1,200000) 58 { 59 for(int j=0;j<c[i].size();j++) S.insert(c[i][j]); 60 while(S.size()>k) 61 { 62 ans[++m]=S.rbegin()->se; 63 S.erase(--S.end()); 64 } 65 while(!S.empty()&&S.begin()->fi==i) S.erase(S.begin()); 66 } 67 printf("%d ",m); 68 rep(i,1,m) printf("%d ",ans[i]); 69 return 0; 70 }