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
题意: 给你n个区间 每次给这个区间加一 问你最后最少有几个区间为k 然后输出这些区间。
思路: 其实就是一个比较强的思维题,,我们设 左端点为-1 右端点为 1 那么排序后 从左边设置一个计数器,
每次计数器减去所扫到的端点的数 ,如果为k 并且前一个点 计数器为k-1 那么这个点就一定是一个起始点。
如果扫到的某个点 前一个点为k 这个点为k 那么它就一定是某个区间的结束点。
代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
#include<algorithm>
#define N 2000005
using namespace std;
int n,k;
pair< int,int >line[N*2];
int sum[N*2];
int main()
{
scanf("%d %d",&n,&k);
int l,r;
int tot=0;
for(int i=1;i<=n;i++)
{
scanf("%d %d",&l,&r);
line[++tot]=make_pair(l,-1);
line[++tot]=make_pair(r,1);
}
sort(line+1,line+tot+1);
vector<int>ans1,ans2;
for(int i=1;i<=tot;i++)
{
sum[i]=sum[i-1]-line[i].second;
if(sum[i]==k&&sum[i-1]==k-1)
{
ans1.push_back(line[i].first);
}
if(sum[i]==k-1&&sum[i-1]==k)
{
ans2.push_back(line[i].first);
}
}
cout<<ans1.size()<<endl;
for(int i=0;i<ans1.size();i++)
{
printf("%d %d\n",ans1[i],ans2[i]);
}
return 0;
}