1. 程式人生 > >洛谷P2434 [SDOI2005]區間

洛谷P2434 [SDOI2005]區間

題目描述

現給定\(n\)個閉區間\([a_i, b_i],1 \leq i \leq n\)。這些區間的並可以表示為一些不相交的閉區間的並。你的任務就是在這些表示方式中找出包含最少區間的方案。你的輸出應該按照區間的升序排列。這裡如果說兩個區間\([a, b]\)\([c, d]\)是按照升序排列的,那麼我們有\(a \leq b<c \leq d\)

請寫一個程式:

讀入這些區間;

計算滿足給定條件的不相交閉區間;

把這些區間按照升序輸出。

輸入輸出格式

輸入格式:

第一行包含一個整數\(n\)\(3 \leq n \leq 50000\),為區間的數目。以下\(n\)行為對區間的描述,第\(i\)

行為對第\(i\)個區間的描述,為兩個整數\(1 \leq ai < bi \leq 1000000\),表示一個區間\([a_i, b_i]\)

輸出格式:

輸出計算出來的不相交的區間。每一行都是對一個區間的描述,包括兩個用空格分開的整數,為區間的上下界。你應該把區間按照升序排序。

輸入輸出樣例

輸入樣例#1:

5
5 6
1 4
10 10
6 9
8 10

輸出樣例#1:

1 4
5 10

思路:考慮差分,每次輸入\(x\)\(y\),於是x的度++,\(y\)的度,然後再掃一遍,累積從\(0\)到+的就是左端點,從+到\(0\)的就是右端點。

程式碼:

#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 1000007
using namespace std;
int n,a[maxn],b[maxn],num,maxx;
inline int qread() {
    char c=getchar();int num=0,f=1;
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) num=num*10+c-'0';
    return num*f;
}
int main() {
    n=qread();
    for(int i=1,x,y;i<=n;++i) {
        x=qread(),y=qread();
        a[x]++,b[y]++;
        maxx=max(maxx,max(x,y));
    }
    for(int i=1;i<=maxx;++i) {
        if(!num&&a[i]) printf("%d ",i);
        num+=a[i]-b[i];
        if(!num&&b[i]) printf("%d\n",i);
    }
    return 0;
}