先按照長度排個序,然後依次新增區間。什麼是新增?設這個區間是[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...