[NOI2016]区间
对于$l_i$、$r_i$的范围太大,我们离散化一下就可以缩到百万的范围了。
这道题要求花费最小。所以根据区间的长度排序,就可以转化成单调性的问题了:选取一段区间,使得这些区间的覆盖存在一个点被覆盖$\geq M$次。
于是维护一颗线段树,然后维护选取区间的开头和结尾,加入区间时将线段树对应的区间修改$+1$,去掉时就$-1$。
当存在一个点被覆盖$m$次时,说明线段树中有一个点的值$=m$,我们通过区间查询判断出来。然后维护答案,此时的答案为选取的区间中最长的减最短的,也就是选取中最后一个减去第一个。
最后输出最小值即可。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define re register 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 7 #define repd(i, a, b) for (re int i = a; i >= b; --i) 8 #define maxx(a, b) a = max(a, b); 9 #define minn(a, b) a = min(a, b); 10 #define LL long long 11 #define INF (1 << 30) 12 13 inline int read() { 14 int w = 0, f = 1; char c = getchar(); 15 while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar(); 16 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar(); 17 return w * f; 18 } 19 20 const int maxn = 500000 + 5; 21 22 struct Seg_tree { 23 #define lson (o << 1) 24 #define rson (o << 1 | 1) 25 int maxv[maxn << 5], tag[maxn << 5]; 26 void pushup(int o) { maxv[o] = max(maxv[lson], maxv[rson]); } 27 void pushdown(int o) { 28 if (!tag[o]) return; 29 tag[lson] += tag[o]; tag[rson] += tag[o]; 30 maxv[lson] += tag[o]; maxv[rson] += tag[o]; 31 tag[o] = 0; 32 } 33 void modify(int o, int l, int r, int ql, int qr, int v) { 34 if (ql <= l && r <= qr) { maxv[o] += v, tag[o] += v; return; } 35 pushdown(o); 36 int mid = (l + r) >> 1; 37 if (ql <= mid) modify(lson, l, mid, ql, qr, v); 38 if (mid < qr) modify(rson, mid+1, r, ql, qr, v); 39 pushup(o); 40 } 41 } T; 42 43 struct Pair { 44 int l, r, sz; 45 } a[maxn]; 46 47 int n, m, b[maxn << 1]; 48 map<int, int> s; 49 bool cmp(Pair a, Pair b) { return a.sz < b.sz; } 50 51 int main() { 52 n = read(), m = read(); 53 rep(i, 1, n) a[i].l = read(), a[i].r = read(), a[i].sz = a[i].r-a[i].l, b[i*2-1] = a[i].l, b[i*2] = a[i].r; 54 sort(b+1, b+n*2+1); 55 int p = 0; b[0] = -INF; 56 rep(i, 1, n*2) { 57 if (b[i] != b[i-1]) p++; 58 s[b[i]] = p; 59 } 60 rep(i, 1, n) a[i].l = s[a[i].l], a[i].r = s[a[i].r]; 61 sort(a+1, a+n+1, cmp); 62 p = 1; 63 int ans = INF; 64 rep(i, 1, n) { 65 T.modify(1, 1, 2*n, a[i].l, a[i].r, 1); 66 while (T.maxv[1] >= m) { 67 minn(ans, a[i].sz-a[p].sz); 68 T.modify(1, 1, 2*n, a[p].l, a[p].r, -1); 69 p++; 70 } 71 } 72 printf("%d", ans == INF ? -1 : ans); 73 return 0; 74 }