BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )

先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了.

--------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
 
using namespace std;
 
#define c(i) o[c[i]]
#define q(i) o[q[i]]
#define H(v) (lower_bound(h, h + n, v) - h)
 
const int maxn = 1000009;
const int INF = 0x3F3F3F3F;
 
inline int read() {
char c = getchar();
int ret = 0;
for(; !isdigit(c); c = getchar());
for(; isdigit(c); c = getchar())
ret = ret * 10 + c - '0';
return ret;
}
 
inline void Max(int &x, int t) {
if(t > x)
x = t;
}
inline void Min(int &x, int t) {
if(t < x)
x = t;
}
 
struct O {
int t, x, y;
O(int _t = 0, int _x = 0, int _y = 0) : t(_t), x(_x), y(_y) {
}
} o[maxn];
 
int N, n, q[maxn], qn, c[maxn], cn, h[maxn], ans[maxn], F;
 
bool cmp(const int &l, const int &r) {
return o[l].x < o[r].x;
}
 
void Init() {
N = read();
int m = read();
for(int i = 0; i < N; i++) {
int x = read(), y = read();
o[i] = O(1, x, y);
}
for(int i = 0; i < m; i++) {
int t = read(), x = read(), y = read();
o[i + N] = O(t, x, y);
}
N += m;
for(int i = 0; i < N; i++)
if(o[i].t == 2) ans[i] = INF;
F = 0;
}
 
struct BIT {
int b[maxn], Mk[maxn];
BIT() {
memset(Mk, -1, sizeof Mk);
memset(b, -INF, sizeof b);
}
inline void Add(int x, int v) {
for(; x <= n; x += x & -x)
if(Mk[x] != F)
Mk[x] = F, b[x] = v;
else
Max(b[x], v);
}
inline int Query(int x) {
int ret = -INF;
for(; x; x -= x & -x)
if(Mk[x] == F) Max(ret, b[x]);
return ret;
}
} Bit;
 
void Work() {
if(!qn || !cn)
return;
sort(q, q + qn, cmp);
sort(c, c + cn, cmp);
n = 0;
for(int i = 0; i < cn; i++)
h[n++] = c(i).y;
for(int i = 0; i < qn; i++)
h[n++] = q(i).y;
sort(h, h + n);
n = unique(h, h + n) - h;
F++;
for(int i = 0, _cn = 0; i < qn; i++) {
while(_cn < cn && c(_cn).x <= q(i).x) {
Bit.Add(H(c(_cn).y) + 1, c(_cn).x + c(_cn).y);
_cn++;
}
Min(ans[q[i]], q(i).x + q(i).y - Bit.Query(H(q(i).y) + 1));
}
F++;
for(int i = qn, _cn = cn - 1; i--; ) {
while(_cn >= 0 && c(_cn).x >= q(i).x) {
Bit.Add(H(c(_cn).y + 1), c(_cn).y - c(_cn).x);
_cn--;
}
Min(ans[q[i]], q(i).y - q(i).x - Bit.Query(H(q(i).y) + 1));
}
F++;
for(int i = 0, _cn = 0; i < qn; i++) {
while(_cn < cn && c(_cn).x <= q(i).x) {
Bit.Add(n - H(c(_cn).y), c(_cn).x - c(_cn).y);
_cn++;
}
Min(ans[q[i]], q(i).x - q(i).y - Bit.Query(n - H(q(i).y)));
}
F++;
for(int i = qn, _cn = cn - 1; i--; ) {
while(_cn >= 0 && c(_cn).x >= q(i).x) {
Bit.Add(n - H(c(_cn).y), -c(_cn).x - c(_cn).y);
_cn--;
}
Min(ans[q[i]], -q(i).x - q(i).y - Bit.Query(n - H(q(i).y)));
}
}
 
void CDQ(int l, int r) {
if(l + 1 >= r)
return;
int m = (l + r) >> 1;
CDQ(l, m);
CDQ(m, r);
cn = qn = 0;
while(l < m) {
if(o[l].t == 1)
c[cn++] = l;
l++;
}
while(l < r) {
if(o[l].t == 2)
q[qn++] = l;
l++;
}
Work();
}
 
int main() {
Init();
CDQ(0, N);
for(int i = 0; i < N; i++) if(o[i].t == 2)
printf("%d ", ans[i]);
return 0;
}

-------------------------------------------------------------- 

2716: [Violet 3]天使玩偶

Time Limit: 80 Sec  Memory Limit: 128 MB
Submit: 877  Solved: 384
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

100 100
81 23
27 16
52 58
44 24
25 95
34 2
96 25
8 14
97 50
97 18
64 3
47 22
55 28
89 37
75 45
67 22
90 8
65 45
68 93
87 8
61 45
69 72
38 57
58 76
45 34
88 54
27 8
35 34
70 81
25 24
97 97
4 43
39 38
82 68
27 58
2 21
92 88
96 70
97 29
14 53
6 42
1 2
35 84
64 88
63 57
53 40
82 59
49 56
75 72
29 30
50 1
40 83
52 94
22 35
39 1
94 88
89 96
79 46
33 75
31 42
33 95
6 83
90 66
37 54
35 64
17 66
48 37
30 8
95 51
3 51
90 33
29 48
94 78
53 7
1 26
73 35
18 33
99 78
83 59
23 87
4 17
53 91
98 3
54 82
85 92
77 8
56 74
4 5
63 1
26 8
42 15
48 98
27 11
70 98
36 9
78 92
34 40
42 82
64 83
75 47
2 51 55
1 7 62
2 21 62
1 36 39
1 35 89
1 84 15
2 19 24
1 58 53
2 52 34
1 98 49
1 4 100
1 17 25
1 30 56
1 69 43
2 57 23
2 23 13
1 98 25
2 50 27
1 84 63
2 84 81
2 84 77
1 60 23
2 15 27
1 9 51
1 31 11
1 96 56
2 20 85
1 46 32
1 60 88
2 92 48
1 68 5
2 90 17
1 16 46
2 67 5
2 29 83
1 84 70
2 68 27
1 99 33
2 39 89
2 38 28
1 42 3
1 10 60
2 56 29
2 12 60
2 46 51
2 15 73
1 93 42
1 78 82
1 66 20
1 46 17
2 48 5
1 59 61
1 87 59
2 98 72
1 49 3
2 21 10
1 15 4
1 48 14
2 67 75
2 83 77
1 88 65
2 100 93
2 58 83
1 29 80
2 31 88
2 92 94
1 96 66
1 61 82
2 87 24
1 64 83
1 28 87
2 72 90
2 7 3
1 86 3
2 26 53
2 71 2
2 88 24
1 69 60
1 92 44
2 74 94
1 12 78
2 1 2
1 4 73
1 58 5
1 62 14
2 64 58
2 39 45
1 99 27
1 42 21
1 87 2
2 16 98
2 17 21
2 41 20
1 46 72
1 11 62
2 68 29
1 64 66
2 90 42
2 63 35
1 64 71

Sample Output

3
8
6
7
7
6
6
12
11
4
5
6
8
1
7
6
4
9
2
2
8
9
6
4
7
5
8
7
5
5
5
7
7
5
6
6
8
6
0
2
7
12
4
2
8
3
10

HINT

Source

原文地址:https://www.cnblogs.com/JSZX11556/p/5097092.html