codeforces 612D

Description

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.

Sample Input

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


利用了sort()排序,提交过程中 一直出现ac不过,显示 超时问题,怎么也找不到解决问题的办法 ,最后 发现原来是 MAX定义的有错误,定义的数组的大小应当至少是 n的两倍,本来觉得这道题特别难,以至于有种想要放弃的感觉 ,还好自己坚持了下来,所以后自己遇到难题不能轻易放弃,坚持 ,再难得的题也一定做得出来 


#include <iostream>
#include <algorithm>
#include <cstdio>
#define  MAX 2000000
using namespace std;


struct Node
{
    int val,op;//val代表存储的点值,op=1代表该点是线段的左端点,0代表该点是线段的右端点
}num[MAX];


bool cmp(Node a,Node b)//从小到大排序,如果a<b,返回真
{
    if(a.val!=b.val)
        return a.val<b.val;
    else
        return a.op>b.op;//当读入的两个点是相同的时候。把作为线段头端点的点排在前面
}
int main()
{
    
    int k,n,t=0,cot=0,point[MAX];
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)//输入线段对应的点的值
    {
        scanf("%d",&num[t].val);
        num[t++].op=1;
        scanf("%d",&num[t].val);
        num[t++].op=0;
    }
    sort(num,num+t,cmp);//按从小到大对点的大小排序
    int p=0;
    for(int i=0;i<t;i++)//某个区间被覆盖至少k次,
                        //意味着在它前面的区间起点至少有k个且这些区间的终点不能出现在它前面
                        //这样sort下,直接统计,遇到起点加一,终点减一,每k个一记录就行了
    {
        if(num[i].op)
        {
            cot++;
            if(cot==k)
                point[p++]=num[i].val;
        }
        else
        {
            if(cot==k) point[p++]=num[i].val;
            cot--;
        }
    }
    cout<<p/2<<endl;//打印区间的个数,p代表点的个数
    for(int i=0;i<p;i=i+2)//每次输入两个点,所以i每次加2
        cout<<point[i]<<" "<<point[i+1]<<endl;


    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值