D2. Too Many Segments (hard version)
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
The only difference between easy and hard versions is constraints.
You are given n
segments on the coordinate axis OX. Segments can intersect, lie inside each other and even coincide. The i-th segment is [li;ri] (li≤ri) and it covers all integer points j such that li≤j≤ri.
The integer point is called bad if it is covered by strictly more than k
segments.
Your task is to remove the minimum number of segments so that there are no bad points at all.
Input
The first line of the input contains two integers n
and k (1≤k≤n≤2⋅105) — the number of segments and the maximum number of segments by which each integer point can be covered.
The next n
lines contain segments. The i-th line contains two integers li and ri (1≤li≤ri≤2⋅105) — the endpoints of the i-th segment.
Output
In the first line print one integer m
(0≤m≤n) — the minimum number of segments you need to remove so that there are no bad points.
In the second line print m
distinct integers p1,p2,…,pm (1≤pi≤n) — indices of segments you remove in any order. If there are multiple answers, you can print any of them.
Examples
Input
Copy
7 2 11 11 9 11 7 8 8 9 7 8 9 11 7 9Output
Copy
3 4 6 7Input
Copy
5 1 29 30 30 30 29 29 28 30 30 30Output
Copy
3 1 4 5Input
Copy
6 1 2 3 3 3 2 3 2 2 2 3 2 3Output
Copy
4 1 3 5 6pair用法
typedef pair<int,int> P;//!!!!
P a[200005];///!!!!
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> P;//!!!! P a[200005];///!!!! int num[200005]; int n,k; vector<P> G[200005];//!!!! vector<int > ans; int maxx=0; int main() { cin>>n>>k; for(int i=1;i<=n;i++) { int l,r; cin>>l>>r; G[l].push_back(P(r,i));///!!!!!! maxx=max(maxx,r); num[l]++; num[r+1]--; } priority_queue<P> que;//pair优先队列 按照字典序排序 优先大堆 int sum=0; for(int i=1;i<=maxx;i++) { sum+=num[i];//差分 for(auto t:G[i]) que.push(t); while(sum>k)//如果当前已经超过限制,则选r最大的进行删除 { ans.push_back(que.top().second);//!!!!!无括号 pair().first pair().second num[que.top().first+1]++; que.pop(); sum--; } } sort(ans.begin(),ans.end()); int s=ans.size(); printf("%d\n",s); for(int i=0;i<s;i++) { printf("%d ",ans[i]); } }
区间问题贪心 优先队列 pair用法
最新推荐文章于 2024-03-28 18:54:51 发布