Educational Codeforces Round 4 D. The Union of k-Segments

来源:互联网 发布:电子手抄报软件 编辑:程序博客网 时间:2024/04/29 23:31
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 20 5-3 23 8
output
20 23 5
input
3 20 5-3 33 8
output
10 5
这道题的意思是,给n个线段,一个数字k,问在x轴上有多少个区间是被k个线段覆盖,输出被覆盖的区间个数和区间。

这道题本来想用O(1)的标记法,但是由于数据太大,不能定义一个足够大的数组,所以就另外看博客看到了一个方法,那就是,给每个点一个标记,如果是一个线段的开始,标记为0,如果是一个线段的结束,标记为1,然后给区间的数值进行一个排序,这个时候并不是把区间的开始和结束放到一个结构体里面进行排序,而是分开来排序,因为已经标记号是线段的开始还是结束,所以就没必要把数值捆绑到一起,排好序后,就开始从前往后扫,如果是0,就给区间的覆盖线段数+1,如果是1,就给区间的覆盖线段数-1,如此,判断,如果覆盖的线段数为k,就直接存到储存结果的数组里面,如此,在储存结果的数组中,第一个和第二个就是一个区间的开始和结束,以此类推。

#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#include<vector>#include<string>using namespace std;struct node{int lr;int dir;}num[2*1000010];int ans[2*1000010];bool cmp(node a,node b){if(a.lr==b.lr)  return a.dir<b.dir;else  return a.lr<b.lr;}int main(){int n,k;int a,b;int len=0;scanf("%d %d",&n,&k);for(int i=0;i<n;i++){scanf("%d %d",&a,&b);num[len].lr=a;num[len++].dir=0;num[len].lr=b;num[len++].dir=1;}sort(num,num+len,cmp);int count=0;int length=0;for(int i=0;i<len;i++){if(num[i].dir==0){count++;if(count==k)  ans[length++]=num[i].lr;}else{if(count==k)  ans[length++]=num[i].lr; count--; }}printf("%d\n",length/2);for(int i=0;i<length;i+=2)  printf("%d %d\n",ans[i],ans[i+1]);return 0;}

0 0
原创粉丝点击