NOI2016 區間 線段樹+離散化
阿新 • • 發佈:2019-02-07
好久沒水線段樹題了。。。
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;
}