題解 P1712 NOI2016 區間

2021-08-21 03:50:24 字數 2707 閱讀 2990

先按照長度排個序,然後依次新增區間。什麼是新增?設這個區間是[l

,r] [l,

r]

,新增就是把al

,al+

1,al

+2,.

..,a

r al,

al+1

,al+

2,..

.,ar

都加上1 1

,其中ai

' role="presentation" style="position: relative;">aia

i表示第

i i

個位置被幾個區間覆蓋。拿走乙個區間的含義就是把它們都減

1' role="presentation" style="position: relative;">1

1。這個過程很顯然可以用線段樹維護。

如果在新增到乙個區間

i i

時,有乙個點被區間覆蓋了

m' role="presentation" style="position: relative;">m

m次,那麼先更新答案,再把前面的加入過的區間一直拿直到沒有乙個點被覆蓋

m m

次。如何判斷有沒有點被覆蓋

m' role="presentation" style="position: relative;">m

m次?因為是乙個乙個區間加的,所以只用維護乙個ai

a

i的最大值,看他是否=m

=

m就行了。

什麼叫再把前面的加入過的區間一直拿直到沒有乙個點被覆蓋

m m

比如你一直新增區間到第

5' role="presentation" style="position: relative;">5

5個,此時有乙個點被覆蓋了

m m

次。這時你就將第乙個區間拿出,如果此時依然有有乙個點被覆蓋了

m' role="presentation" style="position: relative;">m

m次,那麼你就拿走第二個…

這個過程就好比乙個佇列,可以從後面新增區間達到乙個點被覆蓋了

m m

次;從前面彈出區間直到沒有乙個點被覆蓋了

m' role="presentation" style="position: relative;">mm次。

差不多就是這樣,還有注意一下li

,ri≤

109li,

ri≤10

9,開線段樹是要離散化的。上**:

#include 

#include

#include

#include

using

namespace

std;

const

int maxn = 1000500;

int n, m, l[maxn], r[maxn], lid[maxn], rid[maxn], cnt;

struct node pool[maxn * 3], *root;

struct xianduan

}b[maxn];

struct getin

}a[maxn * 2];

inline

void pushdown(node *r)

inline

void pushup(node *r)

inline

void build(node *r, int left, int right)

inline

void change(node *r, int left, int right, int d)     

pushdown(r);

if(r->ch[0]->right >= right) change(r->ch[0], left, right, d);    

else

if(r->ch[1]->left <= left) change(r->ch[1], left, right, d);     

else change(r->ch[0], left, r->ch[0]->right, d), change(r->ch[1], r->ch[1]->left, right, d);

pushdown(r->ch[0]), pushdown(r->ch[1]), pushup(r);

}                      

int main()   

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

a[0].d = -1; 

for(int i = 1; i <= 2 * n; i++)  

build(root, 1, a[2 * n].nid);

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

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

int last = 1, ans = 2147483647;

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

} if(ans == 2147483647) ans = -1;

printf("%d\n", ans);

return

0;}

不要試圖提交我的**,你會因為一些奇怪的空格花式ce的。

題解 NOI2016區間

two pointer 第一題 大概就是對於一段連續的區間求解,使用兩個指標不斷卡區間的長度直到區間不滿足條件吧。這題只要對區間以長度從小到大排一下序,然後使用兩個指標指向區間。線段樹維護被覆蓋最多次數的節點被覆蓋了多少次。如果滿足條件,由於我們是在第一次判斷的時候發現它滿足條件的,所以最後加入的這...

NOI2016 區間 題解

題目大意 有n個區間,當有m個區間有公共部分時,求m個區間長度的最大值與最小值之差的最小值。思路 按區間的長度從小到大排序,可知連續的幾個區間最優,則用兩個指標指其頭尾,線性掃瞄,再用線段樹區間覆蓋。1 include2 include3 include4 define n 1000009 5 de...

luogu P1712區間 題解

noi2016 區間 在數軸上有nn 個閉區間 l 1,r 1 l 2,r 2 l n,r n l1 r1 l2 r2 ln rn 現在要從中選出mm個區間,使得這mm 個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 xx 使得對於每乙個被選中的區間 l i,r i li ri 都有 l i...