線段樹 NOI2016 區間

2021-07-15 22:42:49 字數 3007 閱讀 2376

在數軸上有

n 個閉區間 [l

1,r1

],[l

2,r2

],..

.,[l

n,rn

]。現在要從中選出

m 個區間,使得這

m個區間共同包含至少乙個位置。換句話說,就是使得存在乙個

x ,使得對於每乙個被選中的區間 [l

i,ri

],都有 li

≤x≤r

i 。

對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。區間 [l

i,ri

] 的長度定義為 ri

−li ,即等於它的右端點的值減去左端點的值。

求所有合法方案中最小的花費。如果不存在合法的方案,輸出 −1

。第一行包含兩個正整數 n,

m ,用空格隔開,意義如上文所述。保證 1≤

m≤n 。

接下來

n 行,每行表示乙個區間,包含用空格隔開的兩個整數 li

和 ri 為該區間的左右端點。

只有一行,包含乙個正整數,即最小花費。

如圖,當 n=

6,m=

3 時,花費最小的方案是選取 [3

,5] 、[3

,4] 、[1

,4] 這三個區間,他們共同包含了

4 這個位置,所以是合法的。其中最長的區間是 [1

,4],最短的區間是 [3

,4] ,所以它的花費是 (4

−1)−

(4−3

)=2 。

所有測試資料的範圍和特點如下表所示:

測試點編號

n ml

i,ri

1209 0≤

li≤r

i≤1002

10

3199

3 0≤

li≤r

i≤100000

4200

51000

2

62000

7199

60 0≤

li≤r

i≤5000

8200

50 90

≤li≤

ri≤10

9

101999

500 0≤

li≤r

i≤5000

112000

400

12500

0≤li≤r

i≤109

1330000

2000

0≤li≤r

i≤100000

1440000

1000

1550000

15000

16100000

20000

17200000

0 \le l_i \le r_i \le 10^90≤

li≤r

i≤109

18300000

50000

19400000

90000

20500000

200000

時間限制:3s

空間限制:

256mb

離散化,按照區間長度排序,維護乙個雙指標,滑動視窗,用乙個線段樹來維護點被覆蓋的次數即可。

#include

#include

using

namespace

std;

#define maxn 500000

int r[maxn*2+10],rcnt,m,n,ans=0x7fffffff;

struct itv

inline itv(int l,int r):l(l),r(r),len(r-l)

bool

operator

inline

void push_down(int i)

if(tree[i].tagp)

}inline

void update(int i)

void insert(int i,int l,int r,int ll,int rr,int d)

if(ll>r||rrreturn;

int mid((l+r)>>1);

push_down(i);

insert(i<<1,l,mid,ll,rr,d);

insert((i<<1)|1,mid+1,r,ll,rr,d);

update(i);

}int get_mx(int i,int l,int r,int ll,int rr)

void read(int &x)

}}void read()

sort(r+1,r+rcnt+1);

rcnt=unique(r+1,r+rcnt+1)-r-1;

for(i=1;i<=n;i++)

sort(a+1,a+n+1);

}void solve()

if(tree[1].mxbreak;

ans=min(ans,a[j-1].len-a[i].len);

insert(1,1,rcnt,a[i].l,a[i].r,-1);

i++;

}}int main()

NOI2016 區間 線段樹

在數軸上有 n個閉區間 l1,r1 l2,r2 ln,rn 現在要從中選出 m 個區間,使得這 m個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 x,使得對於每乙個被選中的區間 li,ri 都有 li x ri。對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。...

NOI2016 區間 線段樹

將區間按照長度排序,每次將相同長度的區間插入,直到有乙個點能被至少m個區間覆蓋,這個可以用線段樹維護。這時我們就可以刪除長度小的區間直到不滿足條件。重複做就可以了 1 include 2 include 3 include 4 include 5 include 6 define ll long l...

NOI 2016 區間(雙指標 線段樹)

noi 2016 區間 首先離散化,然後對所有區間按照區間長度排序。然後用雙指標。雙指標保持 l r 這段的所有區間疊加後存在疊加次數為 m 的點。然後 an s等於每一次合法時的最小值。這樣顯然是對的。因為乙個合法的答案一定在某次雙指標區間內計數。include define lson rt 1 ...