题面

传送门

KDTree

大概就是一个分割\(k\)维空间的数据结构,二叉树

建立:每层选取一维为关键字,把中间的点拿出来,递归左右,有个\(STL\)函数nth_element可以用一下

维护:维护当前这个点的子树的每一维的最大值和最小值,相当于维护了个高维矩形

查询:直接遍历一棵树是\(O(n)\)的,利用一些独特的性质可以剪枝,因题而异

奇技淫巧:

  1. 把坐标绕原点转\(\alpha\)度
  2. 定期重构或者像替罪羊树一样,利用平衡因子判断是否需重构
  3. 每次查询到某一层优先选取答案可能最优的一个儿子先递归
  4. 等等

Sol

\(KDTree\)模板题

利用替罪羊树的思想重构

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll; IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} const int maxn(1e6 + 5);
const int inf(2e9);
const double alpha(0.75); int n, op, rt, q, ans, p[maxn], tot, num, cnt; struct Point{
int d[2]; IL int operator <(RG Point a) const{
return d[op] < a.d[op];
}
} a[maxn]; struct KDTree{
int ch[2], d[2], size;
int mn[2], mx[2];
} tr[maxn]; IL void Chkmax(RG int &x, RG int y){
if(y > x) x = y;
} IL void Chkmin(RG int &x, RG int y){
if(y < x) x = y;
} IL int NewNode(){
return tot ? p[tot--] : ++cnt;
} IL void Update(RG int x){
RG int ls = tr[x].ch[0], rs = tr[x].ch[1];
tr[x].mx[0] = tr[x].mn[0] = tr[x].d[0];
tr[x].mx[1] = tr[x].mn[1] = tr[x].d[1];
tr[x].size = tr[ls].size + tr[rs].size + 1;
if(ls){
Chkmin(tr[x].mn[0], tr[ls].mn[0]), Chkmin(tr[x].mn[1], tr[ls].mn[1]);
Chkmax(tr[x].mx[0], tr[ls].mx[0]), Chkmax(tr[x].mx[1], tr[ls].mx[1]);
}
if(rs){
Chkmin(tr[x].mn[0], tr[rs].mn[0]), Chkmin(tr[x].mn[1], tr[rs].mn[1]);
Chkmax(tr[x].mx[0], tr[rs].mx[0]), Chkmax(tr[x].mx[1], tr[rs].mx[1]);
}
} IL int Build(RG int l, RG int r, RG int nop){
op = nop;
RG int x = (l + r) >> 1, nw = NewNode();
nth_element(a + l, a + x, a + r + 1);
tr[nw].d[0] = a[x].d[0], tr[nw].d[1] = a[x].d[1];
if(l < x) tr[nw].ch[0] = Build(l, x - 1, nop ^ 1);
if(x < r) tr[nw].ch[1] = Build(x + 1, r, nop ^ 1);
Update(nw);
return nw;
} IL int Check(RG int x){
return alpha * tr[x].size < tr[tr[x].ch[0]].size || alpha * tr[x].size < tr[tr[x].ch[1]].size;
} IL void ReCycle(RG int x){
if(!x) return;
ReCycle(tr[x].ch[0]), tr[x].ch[0] = 0;
p[++tot] = x, a[++num].d[0] = tr[x].d[0], a[num].d[1] = tr[x].d[1];
ReCycle(tr[x].ch[1]), tr[x].ch[1] = 0;
} IL int ReBuild(RG int x, RG int nop){
num = 0, ReCycle(x);
return Build(1, num, nop);
} IL void Insert(RG int &x, RG int nop, RG Point np){
if(!x){
x = NewNode();
tr[x].d[0] = np.d[0], tr[x].d[1] = np.d[1];
tr[x].mx[0] = tr[x].mn[0] = tr[x].d[0];
tr[x].mx[1] = tr[x].mn[1] = tr[x].d[1];
return;
}
if(np.d[nop] < tr[x].d[nop]) Insert(tr[x].ch[0], nop ^ 1, np);
else Insert(tr[x].ch[1], nop ^ 1, np);
Update(x);
if(Check(x)) x = ReBuild(x, nop);
} IL int Calc(RG int x, RG Point np){
RG int d = max(np.d[0] - tr[x].mx[0], 0) + max(tr[x].mn[0] - np.d[0], 0);
return d + max(tr[x].mn[1] - np.d[1], 0) + max(np.d[1] - tr[x].mx[1], 0);
} IL void Query(RG int x, RG Point np){
RG int d = abs(tr[x].d[0] - np.d[0]) + abs(tr[x].d[1] - np.d[1]), d1 = inf, d2 = inf;
Chkmin(ans, d);
if(tr[x].ch[0]) d1 = Calc(tr[x].ch[0], np);
if(tr[x].ch[1]) d2 = Calc(tr[x].ch[1], np);
RG int c = 0;
if(d1 > d2) swap(d1, d2), c ^= 1;
if(d1 < ans) Query(tr[x].ch[c], np);
if(d2 < ans) Query(tr[x].ch[!c], np);
} int main(){
n = Input(), q = Input();
for(RG int i = 1; i <= n; ++i) a[i].d[0] = Input(), a[i].d[1] = Input();
rt = Build(1, n, 0);
for(RG int i = 1; i <= q; ++i){
RG int t = Input(), x = Input(), y = Input();
if(t == 1) Insert(rt, 0, (Point){x, y});
else{
ans = inf;
Query(rt, (Point){x, y});
printf("%d\n", ans);
}
}
return 0;
}

KDTree(Bzoj2648: SJY摆棋子)的更多相关文章

  1. BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶

    BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...

  2. [BZOJ2648] SJY摆棋子 kd-tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 5421  Solved: 1910[Submit][Status][Disc ...

  3. BZOJ2648 SJY摆棋子(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  4. [bzoj2648]SJY摆棋子(带插入kd-tree)

    解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ...

  5. 【kd-tree】bzoj2648 SJY摆棋子

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

  6. 2019.01.14 bzoj2648: SJY摆棋子(kd-tree)

    传送门 kd−treekd-treekd−tree模板题. 题意简述:支持在平面上插入一个点,求对于一个点的最近点对. 思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息 所以我用了 ...

  7. Bzoj2648 SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 3128  Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ...

  8. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

  9. 【BZOJ2648】SJY摆棋子(KD-Tree)

    [BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ...

随机推荐

  1. Python 字符串前面加u,r,b,f的含义

    1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用: 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时 ...

  2. vue进行路由拼图的使用案例

    实现思路,利用路由进行实现多个组件拼图: Detail.vue <template> <div> <h1>详细展示</h1> <div>鞍山 ...

  3. shiro原理及其运行流程介绍

    shiro原理及其运行流程介绍 认证执行流程 1.通过ini配置文件创建securityManager 2.调用subject.login方法主体提交认证,提交的token 3.securityMan ...

  4. 安卓手机移动端Web开发调试之Chrome远程调试(Remote Debugging)

    一.让安卓打debug模式的apk包 二.将电脑中的chrome升级到最新版本,在chrome浏览器地址栏中输入chrome://inspect/#devices: 在智能手机还未普及时,移动设备的调 ...

  5. JS正则表达式端口号,IP地址

    端口号:65535 正则:/^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6 ...

  6. SpringMVC初写(六)静态资源设置

    众所周知,SpringMVC的DispatchServlet是不可以以/*规则拦截请求的,否则会将JSP都拦截了,但有时候我们的请求路径是不能有后缀(Resful风格的接口需要),基于上述情况,我们可 ...

  7. IIS7如何实现访问HTTP跳转到HTTPS访问 转的

    加几句,1.安装url重写模块,不需要重启IIS,安装完了就能用.个人感觉比 IIS REWRITE组件更好用,iis rewrite是安装第三方的那种,不缴费只可以把所有规则写在一起,不能区别站点, ...

  8. 开源一个Java Class实现Openfire登陆、推出、消息发送,方便其他系统集成IM功能了

    开源一个Java Class实现Openfire登陆.推出.消息发送 N年前写的,希望对Openfire开发新手有帮助哦 import java.util.*; import java.io.*;   ...

  9. Git的介绍和使用

    Git是目前世界上最先进的分布式版本控制系统 Git的安装 1.在linux上安装 你可以先输入git,看看系统是不是已经自带了git 或者 sudo apt-get install git  就可以 ...

  10. python-pymongo使用

    #-*- coding: utf-8 -*- #python2.7x from pymongo import MongoClient def get_db(): #建立连接 client = Mong ...