P1712 [NOI2016]区间
status


线段树维护单点最大值+队列

注意的一点:在下图时

1
2
105 |   while (res(1) == m && pos <= i) {
| ~~~~~~~^~~~

由于满足题目限制条件,所以要更新答案!
否则100pts->60pts


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define l(x) t[(x)].l
#define r(x) t[(x)].r
#define tag(x) t[(x)].tag
#define res(x) t[(x)].max
using namespace std;

const int MAXN = 5e6 + 10;

struct Segment {
int max;
int l;
int r;
int tag;
}t[MAXN << 3];

struct Interval {
int x, y;
int l;
bool operator < (const Interval &p) {
return l < p.l;
}
}p[MAXN];

int base[MAXN << 1], n, m, cnt;

void build(int p, int x, int y) {
l(p) = x, r(p) = y;
if (x != y) {
int mid = (x + y) >> 1;
build(p << 1, x, mid);
build(p << 1 | 1, mid + 1, y);
}
}

inline void pushdown(int p) {
if (l(p) != r(p) && tag(p) != 0) {
int x = tag(p);
tag(p << 1) += x;
res(p << 1) += x;
tag(p << 1 | 1) += x;
res(p << 1 | 1) += x;
tag(p) = 0;
}
}

void printtree(int p) {
printf("--%d:[%d,%d]--\n", p, l(p), r(p));
printf("max=%d\n", res(p));
printf("tag=%d\n", tag(p));
if (l(p) != r(p)) {
printf("ls: %d, rs: %d\n", p << 1, p << 1 | 1);
printtree(p << 1);
printtree(p << 1 | 1);
}
}

void modify(int p, int x, int y, int val) {
if (x > y) return;
if (x <= l(p) && r(p) <= y) {
tag(p) += val;
res(p) += val;
return;
}
int mid = (l(p) + r(p)) >> 1;
pushdown(p);
if (x <= mid) {
modify(p << 1, x, y, val);
}
if (mid < y) {
modify(p << 1 | 1, x, y, val);
}
res(p) = max(res(p << 1), res(p << 1 | 1));
}

int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].l = p[i].y - p[i].x;
base[++cnt] = p[i].x;
base[++cnt] = p[i].y;
}
sort(base + 1, base + cnt + 1);
cnt = unique(base + 1, base + cnt + 1) - base - 1;
for (int i = 1; i <= n; i++) {
p[i].x = lower_bound(base + 1, base + cnt + 1, p[i].x) - base;
p[i].y = lower_bound(base + 1, base + cnt + 1, p[i].y) - base;
// printf("[%d->%d]:%d\n", p[i].x, p[i].y, i);
}
sort(p + 1, p + n + 1);
build(1, 1, cnt);
int pos = 1, ans = 0x3f3f3f3f;
for (int i = 1; i <= n; i++) {
// printf("-------------------------pushin:%d-------------------------\n", i);
// printf("modify : %d->%d:1\n", p[i].x, p[i].y);
modify(1, p[i].x, p[i].y, 1);
// printtree(1);
if (res(1) == m) {
ans = min(ans, p[i].l - p[pos].l);
}
while (res(1) == m && pos <= i) {
// printf("---------------------------------pushup:%d--------------------\n", pos);
// printf("---res=%d,m=%d---\n", res(1), m);
ans = min(ans, p[i].l - p[pos].l);
if (pos != 0) {
// printf("modify : %d->%d:-1\n", p[pos].x, p[pos].y);
modify(1, p[pos].x, p[pos].y, -1);
// printtree(1);
}
pos++;
}
}
if (ans != 0x3f3f3f3f)
printf("%d\n", ans);
else
puts("-1");
return 0;
}