HYSBZ bzoj 2648 SJY摆棋子
2017-10-12 16:58
453 查看
Problem
www.lydsy.com/JudgeOnline/problem.php?id=2648vjudge.net/contest/187908#problem/D
Meaning
棋盘上有 n 个黑子,有 m 个操作,每次可以:放一个黑子;
或放一个白子,顺便查询离与它曼哈顿距离最近的黑子的曼哈顿距离
Analysis
对前面的 n 个点常规地建一棵 K-D树,对后来的黑子就插入,白子只查询最近距离而不查询。Code
#include <cmath> #include <cstdio> #include <algorithm> using namespace std; const int N = 500000, M = 500000, D = 2, BIG = 0x7f7f7f7f; int idx; struct node { int v[D]; bool operator < (const node &rhs) const { return v[idx] < rhs.v[idx]; } } kdt[N+M], aim; int big[N+M][D], sml[N+M][D], lc[N+M], rc[N+M]; void pushup(int p) { for(int i = 0; i < D; ++i) { int &b = big[p][i], &s = sml[p][i]; if(~lc[p]) { b = max(b, big[lc[p]][i]); s = min(s, sml[lc[p]][i]); } if(~rc[p]) { b = max(b, big[rc[p]][i]); s = min(s, sml[rc[p]][i]); } } } int build(int l, int r, int d) { idx = d & 1; int m = l + r >> 1; nth_element(kdt + l, kdt + m, kdt + r + 1); lc[m] = rc[m] = -1; for(int i = 0; i < D; ++i) big[m][i] = sml[m][i] = kdt[m].v[i]; if(l < m) lc[m] = build(l, m - 1, d + 1); if(r > m) rc[m] = build(m + 1, r, d + 1); pushup(m); return m; } int sz; int add() { int p = sz++; lc[p] = rc[p] = -1; for(int i = 0; i < D; ++i) big[p][i] = sml[p][i] = kdt[p].v[i] = aim.v[i]; return p; } /* 插入黑子 */ void insert(int rt, int d) { idx = d & 1; if(aim < kdt[rt]) // 分到左子树的区域 if(~lc[rt]) insert(lc[rt], d + 1); else lc[rt] = add(); else // 分到右子树的区域 if(~rc[rt]) insert(rc[rt], d + 1); else rc[rt] = add(); pushup(rt); } int manhattan(int p) { return abs(aim.v[0] - kdt[p].v[0]) + abs(aim.v[1] - kdt[p].v[1]); } int evaluate(int p) { int res = 0; for(int i = 0; i < D; ++i) if(aim.v[i] > big[p][i]) res += aim.v[i] - big[p][i]; else if(aim.v[i] < sml[p][i]) res += sml[p][i] - aim.v[i]; return res; } int ans; void query(int rt) { ans = min(ans, manhattan(rt)); int dl = BIG, dr = BIG; if(~lc[rt]) dl = evaluate(lc[rt]); if(~rc[rt]) dr = evaluate(rc[rt]); if(dl < dr) { if(dl < ans) query(lc[rt]); if(dr < ans) query(rc[rt]); } else { if(dr < ans) query(rc[rt]); if(dl < ans) query(lc[rt]); } } int main() { int n, m; scanf("%d%d", &n, &m); for(int i = 0; i < n; ++i) for(int j = 0; j < D; ++j) scanf("%d", &kdt[i].v[j]); int rt = build(0, n - 1, 0); sz = n; for(int i = 0, t; i < m; ++i) { scanf("%d%d%d", &t, &aim.v[0], &aim.v[1]); if(t == 1) insert(rt, 0); else { ans = BIG; query(rt); printf("%d\n", ans); } } return 0; }
相关文章推荐
- bzoj 2648 SJY摆棋子 kd树
- BZOJ2648 - SJY摆棋子
- bzoj 2648: SJY摆棋子 (KD-tree)
- [BZOJ2648] SJY摆棋子 kd-tree
- bzoj2648 SJY摆棋子
- [BZOJ2648]SJY摆棋子-K-D树
- BZOJ2648 - SJY摆棋子
- BZOJ 2648 SJY摆棋子 ——KD-Tree
- BZOJ2648 SJY摆棋子
- 【BZOJ2648】SJY摆棋子 [KD-tree]
- BZOJ 2648 SJY摆棋子(KD树)
- bzoj2648 SJY摆棋子
- [BZOJ2648]=[BZOJ2716]SJY摆棋子
- BZOJ 2648 SJY摆棋子(KD Tree)
- BZOJ2648: SJY摆棋子(BZOJ2716)
- BZOJ2648 SJY摆棋子
- BZOJ 2648: SJY摆棋子
- BZOJ 2648/2716(SJY摆棋子-KD_Tree)[Template:KD_Tree]
- bzoj 2648: SJY摆棋子(kd tree)
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree