NOI2016 區間 線段樹

2022-02-27 18:32:37 字數 1883 閱讀 9432

在數軸上有 n個閉區間 [l1,r1],[l2,r2],...,[ln,rn]。現在要從中選出 m 個區間,使得這 m個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 x,使得對於每乙個被選中的區間 [li,ri],都有 li≤x≤ri。

對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。區間 [li,ri] 的長度定義為 ri−li,即等於它的右端點的值減去左端點的值。

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

第一行包含兩個正整數 n,m用空格隔開,意義如上文所述。保證 1≤m≤n

接下來 n行,每行表示乙個區間,包含用空格隔開的兩個整數 li 和 ri 為該區間的左右端點。

n<=500000,m<=200000,0≤li≤ri≤10^9

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

6 33 5

1 23 4

2 21 5

1 4比較容易想到,如果我們對所選的區間都+1,那麼一定存在某個位置的值》=m

先對區間離散化

這樣我們可以得到乙個\(o(n^3)\)的演算法

區間修改求最值,離散化後用線段樹優化,可以做到\(o(n^2logn)\)

為了進一步減小乙個n,我們將區間按區間長度排序

從小開始逐個加入線段樹中,直到出現》=m的位置,再嘗試從小開始從線段樹中刪除,直至滿足》=m時再移動右端點

可以證明這樣做的正確性

因為區間過多不影響存在某位置》=m,通過不斷移動右端點,有解一定可以判出

設當前解為len,如果不移動左端點,右端點移動的結果一定不會比len要小

所以在滿足條件的情況下應盡量移動左端點

\(o(nlogn)\)

#include#include#include#include#include#define ll long long int

#define rep(i,n) for (int i = 1; i <= (n); i++)

#define redge(u) for (int k = h[u],to; k; k = ed[k].nxt)

#define bug(s,n) for (int i = 1; i <= (n); i++) cout<57)

while (c >= 48 && c <= 57)

return out * flag;

}struct nodee[maxm];

int b[maxn],bi,tot = 1,n,m,ans = inf;

int mx[4 * maxn],tag[4 * maxn];

inline bool operator <(const node& a,const node& x)

int getn(int x)

void pd(int u)

}void modify(int u,int l,int r,int l,int r,int x)

pd(u);

int mid = l + r >> 1;

if (mid >= l) modify(ls,l,mid,l,r,x);

if (mid < r) modify(rs,mid + 1,r,l,r,x);

mx[u] = max(mx[ls],mx[rs]);

}int main()

r++;

if (r > n) break;

r = b[e[r].r] - b[e[r].l];

modify(1,1,tot,e[r].l,e[r].r,1);

if (mx[1] >= m) ans = min(ans,r - l);

} printf("%d\n",ans == inf ? -1 : ans);

return 0;

}

線段樹 NOI2016 區間

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

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 ...