Educational Codeforces Round 4 D The Union of k-Segments (掃描線)

Mr_Treeeee發表於2020-04-06


D. The Union of k-Segments
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 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


題意:

給你n個一維線段,讓你求重合數>=k的區間。輸出數量和各個區間。


POINT:

用掃描線來做,左端點標記為-1,右端點標記為1。遇做就cnt++,當cnt==k時記錄左端點,代表答案的左端點。

右端點則--,當cnt==k時也記錄,但是這兩個有順序的區別(很重要),詳細看程式碼。

還有就是,端點重複,比如不同的線段的左端點和右端點重合了,那我們先考慮左端點,再考慮右端點,這也是為什麼把左標記-1,把右標記1的原因,這樣sort排序就沒有問題。

pair排序就是先比first,在比second,也可以用結構體來寫和排序。不過這個比較方便。

同理vector也可以用陣列代替。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <map>
#include <string.h>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
#define lt 2*x
#define rt 2*x+1
#define LL long long
typedef pair<LL,LL> pr;
vector<pr> v;
int main()
{
    LL n,k;
    while(~scanf("%lld  %lld",&n,&k))
    {
        v.clear();
        for(int i=1;i<=n;i++)
        {
            LL l,r;
            scanf("%lld %lld",&l,&r);
            v.push_back(make_pair(l,-1));
            v.push_back(make_pair(r,1));
        }
        sort(v.begin(),v.end());
        int cnt=0;
        vector<LL> ans;
        ans.clear();
        for(LL i=0;i<v.size();i++)
        {
            if(v[i].second==-1)
            {
                cnt++;
                if(cnt==k)
                {
                    ans.push_back(v[i].first);
                }
            }
            else
            {
                if(cnt==k) ans.push_back(v[i].first);
                cnt--;
            }
        }
        printf("%d\n",(int)ans.size()/2);
        for(LL i=0;i<ans.size()/2;i++)
        {
            printf("%lld %lld\n",ans[2*i],ans[2*i+1]);
        }
    }
    
    return 0;
}


相關文章