貌似和那道天使玩偶是一样的题?哇是不是有双倍经验辣!
是一道"裸"的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 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen