一道用STL的贪心,正好能够用来学习使用STL库c++
题目大意:给出n条能够内含,相交,分离的线段,若是重叠条数超过k次则为坏点,n,k<2e5学习
因此咱们贪心的想咱们从左往右遍历,若是重合部分条数超过了k,就必须去除线段,(此时从左边看去除线段后不会出现冲突,右边还有剩余不少线段未知)因此咱们选择去除这些重合线段里右端最右的部分spa
实现:3d
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn =2e5+30;
set<pii>res;
vector<pii>v[maxn];
vector<int>ans;
int main(){
int n,k,mx=0,t1,t2;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d%d",&t1,&t2);
v[t1].push_back({t2,i});//左端点t1储存右端点和序号i,C11的用法这里{t2,i}等于make_pair
mx=max(t2,mx);
}
for(int i=0;i<=mx;i++){
while(res.begin()->first <i&&!res.empty())//当右端点小于i时已经彻底扫过,此时删去该线段
res.erase(res.begin());//删去整条线段
for(int j=0;j<v[i].size();j++)
res.insert(v[i][j]);//插入该端点为左端点下的线段
while(res.size()>k){//若是此时重合部分大于k,则找到这些线段里右端点最右的线段,加入ans并删去
ans.push_back(res.rbegin()->second);//rbegin()返回的是最末元素的位置
res.erase(--res.end());//注意虽然效果同样但end和rbegin的类型不同
}
}
cout<<ans.size()<<endl;
for(auto x:ans){
cout<<x<<' ';
}
cout<<endl;
}code
原题连接:https://codeforces.com/contest/1249/problem/D2blog
关于迭代器的tipip