[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 }

 

posted @ 2019-02-13 13:12  AC-Evil  阅读(145)  评论(0编辑  收藏  举报