# BZOJ2648 SJY摆棋子

  1 /**************************************************************
2     Problem: 2648
3     User: rausen
4     Language: C++
5     Result: Accepted
6     Time:8108 ms
7     Memory:60380 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <algorithm>
12
13 using namespace std;
14 const int inf = 0x7f7f7f7f;
15 const int N = 500005;
16 const int Cnt_kd = N << 1;
17 const int Maxlen = N * 5 * 10;
18
19 int n, ans, Dep;
20 char buf[Maxlen], *c = buf;
21 int Len;
22
24   int x = 0, sgn = 1;
25   while (*c < '0' || '9' < *c) {
26     if (*c == '-') sgn = -1;
27     ++c;
28   }
29   while ('0' <= *c && *c <= '9')
30     x = x * 10 + *c - '0', ++c;
31   return sgn * x;
32 }
33
34 struct point {
35   int x[2];
36
37   point(int _x0 = 0, int _x1 = 0) : x({_x0, _x1}) {}
38   inline int& operator [] (int i) {
39     return x[i];
40   }
41   inline bool operator < (const point &p) const {
42     return x[Dep] < p.x[Dep];
43   }
46   }
47 } points[N];
48
49
50 struct kd_node {
51   kd_node *ls, *rs;
52   int mx[2], mn[2];
53   point p;
54 } *kd_root, mempool[Cnt_kd], *cnt_kd = mempool, *null;
55
56 inline int dis(point p, point q) {
57   return abs(p[0] - q[0]) + abs(p[1] - q[1]);
58 }
59
60 #define Ls p -> ls
61 #define Rs p -> rs
62 #define Mx p -> mx
63 #define Mn p -> mn
64 #define P p -> p
65 inline void kd_new(kd_node *&p, point p1) {
66   int i;
67   p = ++cnt_kd;
68   Ls = Rs = null, P = p1;
69   for (i = 0; i < 2; ++i)
70     Mx[i] = Mn[i] = P[i];
71 }
72
73 inline int dist(kd_node *p, point p1) {
74   int res = 0, i;
75   for (i = 0; i < 2; ++i)
76     res += max(0, Mn[i] - p1[i]);
77   for (i = 0; i < 2; ++i)
78     res += max(0, p1[i] - Mx[i]);
79   return res;
80 }
81
82 inline void kd_update(kd_node *p) {
83   int i;
84   for (i = 0; i < 2; ++i) {
85     if (Ls != null) {
86       Mn[i] = min(Mn[i], Ls -> mn[i]);
87       Mx[i] = max(Mx[i], Ls -> mx[i]);
88     }
89     if (Rs != null) {
90       Mn[i] = min(Mn[i], Rs -> mn[i]);
91       Mx[i] = max(Mx[i], Rs -> mx[i]);
92     }
93   }
94 }
95
96 #define mid (l + r >> 1)
97 inline void kd_build(kd_node *&p, int l, int r, int d) {
98   Dep = d;
99   nth_element(points + l, points + mid, points + r + 1);
100   kd_new(p, points[mid]);
101   if (l < mid) kd_build(Ls, l, mid - 1, !d);
102   if (mid < r) kd_build(Rs, mid + 1, r, !d);
103   kd_update(p);
104 }
105 #undef mid
106
107 void kd_insert(kd_node *&p, point p1, int d) {
108   if (p == null) {
109     kd_new(p, p1);
110     return;
111   }
112   if (P[d] > p1[d]) kd_insert(Ls, p1, !d);
113   else kd_insert(Rs, p1, !d);
114   kd_update(p);
115 }
116
117 void kd_query(kd_node *p, point p1, int d) {
118   int dl, dr;
119   ans = min(ans, dis(P, p1));
120   dl = (Ls == null ? inf : dist(Ls, p1));
121   dr = (Rs == null ? inf : dist(Rs, p1));
122   if (dl < dr) {
123     if (dl < ans) kd_query(Ls, p1, !d);
124     if (dr < ans) kd_query(Rs, p1, !d);
125   } else {
126     if (dr < ans) kd_query(Rs, p1, !d);
127     if (dl < ans) kd_query(Ls, p1, !d);
128   }
129 }
130 #undef Ls
131 #undef Rs
132 #undef Mx
133 #undef Mn
134 #undef P
135
136 int main() {
137   Len = fread(c, 1, Maxlen, stdin);
138   buf[Len] = '\0';
139   int i, Q, oper, x, y;
140   point P;
142   null = cnt_kd;
143   null -> ls = null -> rs = null;
144   kd_root = null;
145   for (i = 1; i <= n; ++i)
147   kd_build(kd_root, 1, n, 0);
148   while (Q--) {
150     if (oper == 1) kd_insert(kd_root, P, 0);
151     else {
152       ans = inf;
153       kd_query(kd_root, P, 0);
154       printf("%d\n", ans);
155     }
156   }
157   return 0;
158 }
View Code

By Xs酱~ 转载请说明 博客地址：http://www.cnblogs.com/rausen
posted on 2015-02-16 15:05  Xs酱~  阅读(541)  评论(0编辑  收藏  举报