貌似和那道天使玩偶是一样的题?哇是不是有双倍经验辣!

是一道"裸"的kd_tree,虽然。。。要维护的东西比较多,而且是2d_tree

这题的估价函数的话,要维护每个点的子树形成的平面

 

  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  
 23 inline int read() {
 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   }
 44   inline void read_in() {
 45     x[0] = read(), x[1] = read();
 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;
141   n = read(), Q = read();
142   null = cnt_kd;
143   null -> ls = null -> rs = null;
144   kd_root = null;
145   for (i = 1; i <= n; ++i)
146     points[i].read_in();
147   kd_build(kd_root, 1, n, 0);
148   while (Q--) {
149     oper = read(), P.read_in();
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

 

posted on 2015-02-16 15:05  Xs酱~  阅读(569)  评论(0编辑  收藏  举报