1. 程式人生 > >NOI2016 區間 線段樹+離散化

NOI2016 區間 線段樹+離散化

傳送門

好久沒水線段樹題了。。。

NOI2016的簽到題,差不多就是個裸的線段樹。
離散化,建樹,維護最大值。
然後區間以長度排序,從小到大加入線段,若覆蓋次數達到m就更新答案,同時刪除最左邊的區間,並更新答案(因為有些區間不覆蓋那個已經覆蓋m次的點),就完了。
好像某個最小差值生成樹(霧

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN = 500001;
int l[MAXN], r[MAXN], a[MAXN << 1], b[MAXN << 1];
int
tot; struct Seg{ int l, r, len; }c[MAXN]; struct Segment_Tree{ #define mid ((l + r) >> 1) int val[MAXN << 3], tag[MAXN << 3]; inline void Pushup(int u){ val[u] = max(val[u << 1], val[u << 1 | 1]); } inline void Pushdown(int u){ if(tag[u]){ tag[u <<
1] += tag[u]; val[u << 1] += tag[u]; tag[u << 1 | 1] += tag[u]; val[u << 1 | 1] += tag[u]; tag[u] = 0; } } inline void Change(int u, int l, int r, int L, int R, int k){ if(l >= L && r <= R){val[u] += k; tag[u] += k; return;} Pushdown(u); if(L <= mid)
Change(u << 1, l, mid, L, R, k); if(R > mid) Change(u << 1 | 1, mid + 1, r, L, R, k); Pushup(u); } #undef mid }T; inline int read(){ int k = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){k = k*10 + ch - '0'; ch = getchar();} return k * f; } inline bool cmp(Seg a, Seg b){ return a.len < b.len; } int main(){ int n = read(), m = read(); for(int i = 1; i <= n; i++){ a[++tot] = c[i].l = read(), a[++tot] = c[i].r = read(); c[i].len = c[i].r - c[i].l; } sort(a + 1, a + tot + 1); tot = 0; for(int i = 1; i <= n * 2; i++){ if(i == 1 || a[i] != a[i - 1]){ b[++tot] = a[i]; } } sort(c + 1, c + n + 1, cmp); int Lcur = 1, Ans = 0x7fffffff; for(int Rcur = 1; Rcur <= n; Rcur++){ // printf("val = %d\n", T.val[1]); int L = lower_bound(b + 1, b + tot + 1, c[Rcur].l) - b; int R = lower_bound(b + 1, b + tot + 1, c[Rcur].r) - b; T.Change(1, 1, tot, L, R, 1); if(T.val[1] >= m){ while(T.val[1] >= m && Lcur <= Rcur){ Ans = min(Ans, c[Rcur].len - c[Lcur].len); int L = lower_bound(b + 1, b + tot + 1, c[Lcur].l) - b; int R = lower_bound(b + 1, b + tot + 1, c[Lcur].r) - b; T.Change(1, 1, tot, L, R, -1); Lcur++; } } } if(Ans == 0x7fffffff) Ans = -1; printf("%d", Ans); return 0; }