2716 [Violet 3] 天使玩偶
@(BZOJ)[CDQ分治]
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
Solution
4 * CDQ分治
細節不要寫錯
這份代碼是TLE的, 原因貌似是常數過大QAQ
假如讀者有在代碼中發現任何問題, 懇請告知, 筆者將感激不盡.
#include<cstdio>
#include<cctype>
#include<climits>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int x = 0, flag = 1;
char c;
while(! isdigit(c = getchar()))
if(c == '-')
flag *= - 1;
while(isdigit(c))
x = x * 10 + c - '0', c = getchar();
return x * flag;
}
void println(int x)
{
if(x < 0)
putchar('-'), x *= - 1;
if(x == 0)
putchar('0');
int ans[1 << 4], top = 0;
while(x)
ans[top ++] = x % 10, x /= 10;
for(; top; top --)
putchar(ans[top - 1] + '0');
putchar('\n');
}
const int N = 1 << 19, M = 1 << 19;
const int LIM = 1 << 20;
int n, m;
struct vertex
{
int x, y, opt, ID, time;
inline friend bool operator <= (vertex a, vertex b)
{
if(a.x == b.x)
return a.opt <= b.opt;
return a.x <= b.x;
}
}a[N + M], b[N + M], tmp[N + M];
int ans[M];
int T[LIM << 2];
void modify(int u, int L, int R, int p, int x)
{
if(L + 1 == R)
{
T[u] = x;
return;
}
int mid = L + R >> 1;
if(p < mid)
modify(u << 1, L, mid, p, x);
else
modify(u << 1 | 1, mid, R, p, x);
T[u] = max(T[u << 1], T[u << 1 | 1]);
}
int query(int u, int L, int R, int p)
{
if(p + 1 >= R)
return T[u];
int mid = L + R >> 1;
if(p < mid)
return query(u << 1, L, mid, p);
else
return max(T[u << 1], query(u << 1 | 1, mid, R, p));
}
void cdq(int L, int R)
{
if(L + 1 >= R)
return;
int mid = L + R >> 1;
cdq(L, mid), cdq(mid, R);
for(int i = L; i < R; i ++)
tmp[i] = b[i];
int p1 = L, p2 = mid, p = L;
while(p1 < mid && p2 < R)
{
if(b[p1] <= b[p2])
tmp[p ++] = b[p1 ++];
else
tmp[p ++] = b[p2 ++];
}
while(p1 < mid)
tmp[p ++] = b[p1 ++];
while(p2 < R)
tmp[p ++] = b[p2 ++];
for(int i = L; i < R; i ++)
b[i] = tmp[i];
for(int i = L; i < R; i ++)
{
if(b[i].ID < mid && ! b[i].opt)
modify(1, 0, LIM, b[i].y, b[i].x + b[i].y);
else if(b[i].ID >= mid && b[i].opt)
{
int tmp = query(1, 0, LIM, b[i].y); //注意要特判
if(tmp)
ans[b[i].time] = min(ans[b[i].time], b[i].x + b[i].y - tmp);
}
}
for(int i = L; i < R; i ++)
if(b[i].ID < mid && ! b[i].opt)
modify(1, 0, LIM, b[i].y, 0);
}
void cdqSolve1()
{
for(int i = 0; i < n + m; i ++)
b[i] = a[i];
cdq(0, n + m);
}
void cdqSolve2()
{
for(int i = 0; i < n + m; i ++)
b[i] = a[i], b[i].y = LIM - a[i].y;
cdq(0, n + m);
}
void cdqSolve3()
{
for(int i = 0; i < n + m; i ++)
b[i] = a[i], b[i].x = LIM - a[i].x, b[i].y = LIM - a[i].y;
cdq(0, n + m);
}
void cdqSolve4()
{
for(int i = 1; i <= n + m; i ++)
b[i] = a[i], b[i].x = LIM - a[i].x;
cdq(0, n + m);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("BZOJ2716.in", "r", stdin);
freopen("BZOJ2716.out", "w", stdout);
#endif
n = read(), m = read();
for(int i = 0; i < n; i ++)
a[i].x = read() + 1, a[i].y = read() + 1, a[i].opt = 0, a[i].ID = i, a[i].time = - 1;
for(int i = 0; i < m; i ++)
a[n + i].opt = read() - 1, a[n + i].x = read() + 1, a[n + i].y = read() + 1, a[n + i].ID = i + n, a[n + i].time = i;
memset(ans, 127, sizeof(ans));
memset(T, 0, sizeof(T));
cdqSolve1(), cdqSolve2(), cdqSolve3(), cdqSolve4();
for(int i = 0; i < m; i ++)
if(a[i + n].opt)
println(ans[i]);
}