bzoj2716 [Violet 3]天使玩偶
2716: [Violet 3]天使玩偶
Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 2160 Solved: 936
[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
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
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
分析:只涉及到修改和查询操作,并且允许离线,修改之间互相独立,可以用cdq分治来做.
不好处理的是如何求最近距离,绝对值不好弄.那么考虑将绝对值去掉,分四种情况讨论,每次相当于把坐标系旋转90°,然后统计在询问的点左下方的点中x'+y'最大的,答案是x+y - (x' + y'),可以利用树状数组维护最大值.那么这就和三维偏序问题差不多了:时间,x,y.利用cdq分治处理时间,对x排序,在y上用树状数组维护≤y的最大x'+y'.
比较容易出错的是如果树状数组中查询的max为0,说明没有点在当前点的左下方,需要返回-inf!!!因为一个点到自身的距离不能是它自己的x+y.
最后80s卡时过了,别人都以为我在卡评测,结果突然蹦出一个AC233.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1000010,inf = 0x7ffffff; int n,m,maxx,maxy,ans[maxn],cnt,c[maxn]; struct node { int x,y,id,z,ansid; } e[maxn],p[maxn],t[maxn]; bool cmp(node a,node b) { if (a.x == b.x && a.y == b.y) return a.id < b.id; if (a.x == b.x) return a.y < b.y; return a.x < b.x; } void add(int x,int v) { while (x <= maxy) { c[x] = max(c[x],v); x += x & (-x); } } void clea(int x) { while (x <= maxy) { c[x] = 0; x += x & (-x); } } int query(int x) { int res = 0; while (x) { res = max(res,c[x]); x -= x & (-x); } return res == 0 ? -inf: res; } void solve(int l,int r) { if (l == r) return; int mid = (l + r) >> 1; for (int i = l; i <= r; i++) { if (p[i].id <= mid && p[i].z == 1) add(p[i].y,p[i].x + p[i].y); else if (p[i].id > mid && p[i].z == 2) ans[p[i].ansid] = min(ans[p[i].ansid],p[i].x + p[i].y - query(p[i].y)); } for (int i = l; i <= r; i++) { if (p[i].id <= mid && p[i].z == 1) clea(p[i].y); } int L = l,R = mid + 1; for (int i = l; i <= r; i++) { if (p[i].id <= mid) t[L++] = p[i]; else t[R++] = p[i]; } for (int i = l; i <= r; i++) p[i] = t[i]; solve(l,mid),solve(mid + 1,r); } int main() { scanf("%d%d",&n,&m); for (int i = 1; i <= n; i++) { scanf("%d%d",&e[i].x,&e[i].y); e[i].x++; e[i].y++; maxx = max(maxx,e[i].x); maxy = max(maxy,e[i].y); e[i].id = i; e[i].z = 1; } for (int i = n + 1; i <= n + m; i++) { scanf("%d%d%d",&e[i].z,&e[i].x,&e[i].y); e[i].x++; e[i].y++; if (e[i].z == 2) { ans[++cnt] = inf; e[i].ansid = cnt; } maxx = max(maxx,e[i].x); maxy = max(maxy,e[i].y); e[i].id = i; } maxx++; maxy++; for (int i = 1; i <= n + m; i++) p[i] = e[i]; sort(p + 1,p + 1 + n + m,cmp); solve(1,n + m); for (int i = 1; i <= n + m; i++) { p[i] = e[i]; p[i].x = maxx - p[i].x; } sort(p + 1,p + 1 + n + m,cmp); solve(1,n + m); for (int i = 1; i <= n + m; i++) { p[i] = e[i]; p[i].y = maxy - p[i].y; } sort(p + 1,p + 1 + n + m,cmp); solve(1,n + m); for (int i = 1; i <= n + m; i++) { p[i] = e[i]; p[i].x = maxx - p[i].x; p[i].y = maxy - p[i].y; } sort(p + 1,p + 1 + n + m,cmp); solve(1,n + m); for (int i = 1; i <= cnt; i++) printf("%d\n",ans[i]); return 0; }