You are given n segments on the coordinate axis Ox and the number k. The point is satisfied if it belongs to at least k segments. Find the smallest (by the number of segments) set of segments on the coordinate axis Ox which contains all satisfied points and no others.
The first line contains two integers n and k (1 ≤ k ≤ n ≤ 106) — the number of segments and the value of k.
The next n lines contain two integers li, ri ( - 109 ≤ li ≤ ri ≤ 109) each — the endpoints of the i-th segment. The segments can degenerate and intersect each other. The segments are given in arbitrary order.
First line contains integer m — the smallest number of segments.
Next m lines contain two integers aj, bj (aj ≤ bj) — the ends of j-th segment in the answer. The segments should be listed in the order from left to right.
3 2 0 5 -3 2 3 8
2 0 2 3 5
3 2 0 5 -3 3 3 8
1 0 5
【题意】给了一堆区间,要你把覆盖次数大于等于k的区间全部输出来。
【解题方法】暴力小技巧。暴力扫描分界点,是正向覆盖了k次的就加到左端点,否则加到右断点。
【AC 代码】
#include <bits/stdc++.h>
using namespace std;
pair<int,int>p[3000010];
vector<int>ans1,ans2;
int a[3000010],cnt,n,k,x,y;
int main()
{
scanf("%d%d",&n,&k);cnt=1;
for(int i=1; i<=n; i++){
scanf("%d%d",&x,&y);
p[cnt++]=make_pair(x,-1);
p[cnt++]=make_pair(y,1);
}
sort(p+1,p+cnt);
ans1.clear(),ans2.clear();
memset(a,0,sizeof(a));
for(int i=1; i<cnt; i++){
a[i]=a[i-1]-p[i].second;
if(a[i]==k&&a[i-1]==k-1) ans1.push_back(p[i].first);
}
memset(a,0,sizeof(a));
for(int i=1; i<cnt; i++){
a[i]=a[i-1]-p[i].second;
if(a[i]==k-1&&a[i-1]==k) ans2.push_back(p[i].first);
}
//cout<<ans1.size()<<" "<<ans2.size()<<endl;
if(ans1.size()!=ans2.size()) ans2.push_back(p[cnt-1].first);
printf("%d\n",(int)ans1.size());
for(int i=0; i<(int)ans1.size(); i++){
printf("%d %d\n",ans1[i],ans2[i]);
}
return 0;
}