BZOJ 2648 (SJY-KD_Tree)
2648: SJY Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 1180 Solved: 391
[Submit] [Status] [Discuss] Description: SJY is boring on this day. Play at home. There are N black pawns on a board. Each time he puts either a black pawn on the Board or a white one, if it is a white one, he will find the black one closest to the white one. The distance here is the Manhattan distance (| x1-x2 | + | y1-y2 | ). Now N <= 500000 initial pawns are given. And M <= 500000 operations. For each white piece, the distance from the black piece closest to the white piece is output. A grid may have multiple pawns. The first line of Input is two rows after n m, 3 numbers per row t x y if t = 1 then put a black pawn if t = 2 then put a white pawn Output for each T = 2 Output a minimum distance from Sample Input2 3
1 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
1
2
HINT
Kdtree can be used
Source
Thank sun Jiayu
There is already a kd-tree in the prompt.
Consider a heap of points on the plane, first find the point of the abscissa median, take out, cut a knife, and the remaining points are divided into two halves
Then vertical cutting is performed on one side, and horizontal cutting is performed ....
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; # define For (I, n) for (int I = 1; I <= n; I ++) # define Fork (I, k, n) for (int I = k; I <= n; I ++) # define Rep (I, n) for (int I = 0; I
= 0; I --) # define Forp (x) for (int p = pre [x]; p = next [p]) # define Forpiter (x) for (int & p = iter [x]; p = next [p]) # define Lson (x <1) # define Rson (x <1) + 1) # define MEM (a) memset (a, 0, sizeof (a); # define MEMI (a) memset (a, 127, sizeof ()); # define MEMi (a) memset (a, 128, sizeof (a); # define INF (1000000000) # define F (100000007) # define MAXN (500000 + 10) # define MAXM (500000 + 10) typedef long ll; ll mul (ll a, ll B) {return (a * B) % F;} ll add (ll, ll B) {return (a + B) % F;} ll sub (ll a, ll B) {return (a-B + (a-B) /F * F + F) % F;} void upd (ll & a, ll B) {a = (a % F + B % F) % F;} int n, m; int cmp_d = 0; class node {public: int x [2]; int l, r, minv [2], maxv [2]; node () {} node (int a, int B) {MEM (x) l = r = 0; x [0] = a, x [1] = B; Rep (I, 2) minv [I] = maxv [I] = x [I];} int & operator [] (int I) {return x [I] ;}}; int dis (node a, node B) {int ans = 0; Rep (I, 2) ans + = abs (. x [I]-B. x [I]); return ans;} int dis2 (node p, node a) // Euclidean distance between point p and Square area a {int ans = 0; Rep (I, 2) {if (p. x [I]. maxv [I]) ans + = p. x [I]-. maxv [I];} return ans;} int cmp (node a, node B) {return a [cmp_d]
> 1; cmp_d = nowd; nth_element (a + L + 1, a + m + 1, a + R + 1, cmp); if (L ^ m) a [m]. l = build (L, M-1, nowd ^ 1); if (R ^ m) a [m]. r = build (m + 1, R, nowd ^ 1); update (a [m]); return m;} int root; void _ build (int L, int R, int nowd) {root = build (L, R, nowd);} void insert (int o, int k, int nowd) {int p = a [o]. x [nowd]; int p2 = a [k]. x [nowd]; if (p2 <= p) {if (a [o]. l) insert (a [o]. l, k, nowd ^ 1); else a [o]. l = k;} else {if (a [o]. r) insert (a [o]. r, k, nowd ^ 1); else a [o]. r = k ;} Update (a [o]);} void _ insert (int k, int nowd) {int p = root; insert (root, k, nowd);} node _ p; int _ ans; void ask_min_dis (int o) {if (o = 0) return; _ ans = min (_ ans, dis (a [o], _ p )); int ans1 = a [o]. l? Dis2 (_ p, a [a [o]. l]): INF; // the minimum value of the distance between point p and any point in the area int ans2 = a [o]. r? Dis2 (_ p, a [a [o]. r]): INF; if (ans1> n> m; For (I, n) {int x, y; scanf (% d, & x, & y); S. a [I] = node (x, y);} S. a [++ n] = node (INF, INF); S. _ build (1, n, 0); For (I, m) {int p, x, y; scanf (% d, & p, & x, & y); if (p = 1) {S. a [++ n] = node (x, y); S. _ insert (n, 0);} else {printf (% d, S. _ ask (node (x, y) ;}} return 0 ;}