D. The Union of k-Segments
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.Input 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.Output 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.
Examples
input
3 2 0 5
-3 2 3 8
output
2 0 2 3 5
input
3 2 0 5
-3 3 3 8
output
1 0 5
http://codeforces.com/contest/612/problem/D
题目大意:
给定n个区间,和k。给定的n个区间[l,r]会有重合,问有多少个区间,区间的重合个数大于k,并且输出区间
比如:n=2,k=2,给定俩区间[1,3],[2,4],那么重合的部分就是[2,3],并且重合的区间个数为2,大于等于k,所以输出[2,3]这个区间。
解题思路:
把每一个点封装成结构体,如果是左端点就flag=1,否则为-1。
然后把所有节点按从小到大排好序,从左到右扫描,遇见左端点就+1,否则减一(也就是value+=flag)
也就是用前缀和处理
如果觉得难理解,就手动模拟一下场景,我也是这样才明白的
#include <bits/stdc++.h>
using namespace std;
typedef struct segment
{
int side,flag;
bool operator <(const segment s)const
{
if(this->side != s.side)
return this->side < s.side;
else
return this->flag >s.flag;
}
}segment;
segment seg[2000005];
segment ans[2000005];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d %d",&seg[2*i].side, &seg[2*i+1].side);
seg[2*i].flag=1;
seg[2*i+1].flag=-1;
}
//共有2*n个点
sort(seg,seg+2*n);
int cnt=0,val=0;
for(int i=0;i<2*n;i++)
{
val+=seg[i].flag;
// printf("val=%d\n",val);
if(k==val)
{
// printf("i=%d\n",i);
ans[cnt++].side=i;
while(k<=val && i<2*n)
{
i++;
val+=seg[i].flag;
// printf("k==%d\n",k);
}
ans[cnt++].side=i;
// printf("aa==%d\n",ans[cnt-1].side);
}
}
// printf("cnt=%d\n",cnt);
printf("%d\n",cnt/2);
for(int i=0;i<cnt/2;i++)
{
// printf("%d %d\n",ans[2*i].side ,ans[2*i+1].side);
// 注意ans里面存的仅仅是下标,需要放到seg里面才能取值
printf("%d %d\n",seg[ans[2*i].side].side,seg[ans[2*i+1].side].side);
}
return 0;
}
/*
2 2
1 3
2 4
*/