博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
K-D树
阅读量:3955 次
发布时间:2019-05-24

本文共 2364 字,大约阅读时间需要 7 分钟。

K-D树

dim维空间中,维护一堆点,可以快速查询离某个点最近的点。

  1. 建树。第a层按照第a%dim维中值分为左子树和右子树, O ( n log ⁡ n ) O(n\log n) O(nlogn)
  2. 删除和新增节点。替罪羊树的思路,删除即标记已删除,新增直接插入。不平衡就拆掉这个子树重建。
  3. 查询。按照每个点在树节点那一维的左边还是右边,先查那一个子树,再判断全局最小距离比查询点到分界线的距离大,则再查另外一个子树。
#include 
#define endl '\n'#define ls rt << 1#define rs rt << 1 | 1using namespace std;using ll = long long;using pii = pair
;const int maxn = 2e5 + 5;int k;ll mind;struct ooo{
int v[2], c, mi, id; bool operator< (const ooo& ot) const& {
return v[k] < ot.v[k]; } friend istream& operator>> (istream &in, ooo &ot){
in >> ot.v[0] >> ot.v[1] >> ot.c; ot.mi = ot.c; // 子树最小c值 return in; }}data[maxn], tr[maxn<<2], cur, obj;bool leg[maxn<<2]; // 合法点ll dis(const ooo& a, const ooo& b){
ll ans = 0; for(int i=0;i<2;++i){
ans += ll(a.v[i] - b.v[i]) * (a.v[i] - b.v[i]); } return ans; // if need, sqrt}void build(int rt, int l, int r, int dir){
if(r < l)return; k = dir; int mid = l+r>>1; nth_element(data+l, data+mid, data+r+1); leg[rt] = true; tr[rt] = data[mid]; dir = (dir+1)%2; if(l < mid){
build(ls, l, mid-1, dir); tr[rt].mi = min(tr[rt].mi , tr[ls].mi); } if(mid < r){
build(rs, mid+1, r, dir); tr[rt].mi = min(tr[rt].mi, tr[rs].mi); }}void query(int rt, int dir){
if(!leg[rt])return; if(obj.c < tr[rt].mi)return; k = dir; ll d = dis(tr[rt], obj); if(obj.c >= tr[rt].c){
if(mind == d && tr[rt].id < cur.id || mind > d){
cur = tr[rt]; mind = d; } } int son; if(obj.v[k] < tr[rt].v[k]) son = ls; else son = rs; ll val = ll(obj.v[dir]-tr[rt].v[dir]) * (obj.v[dir]-tr[rt].v[dir]); // 到分界线的直线距离 dir = (dir + 1) % 2; query(son, dir); if(val <= mind) query(son^1, dir);}int main(){
ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int tt; cin >> tt; while(tt--){
memset(leg, 0, sizeof(leg)); int n, m; cin >> n >> m; for(int i=1; i<=n;++i){
cin >> data[i]; data[i].id = i; } build(1, 1, n, 0); while(m--){
cin >> obj; mind = 1e18; cur.id = maxn; query(1, 0); cout << cur.v[0] << ' ' << cur.v[1] << ' ' << cur.c << endl; } }}

转载地址:http://uwuzi.baihongyu.com/

你可能感兴趣的文章
mysql 创建单表外键关联多表
查看>>
postman使用
查看>>
ClassNotFoundException和NoClassDefFoundError的区别
查看>>
Tomcat Connector三种运行模式(BIO, NIO, APR)的比较和优化
查看>>
spring注解@Primary与@Qualifier
查看>>
annotation之@Autowired、@Inject、@Resource三者区别
查看>>
idea启动微服务找不到配置文件
查看>>
Java通过反射机制调用某个类的方法
查看>>
字节跳到面试题
查看>>
Linux查看物理CPU个数
查看>>
Linux学习之网络IO,磁盘io
查看>>
ES7.6.2安装
查看>>
查看jar依赖树
查看>>
idea运行gradle项目
查看>>
es安装ltr插件
查看>>
开源ltr-es-7.6.2代码到本地idea打开出现各种错误总结
查看>>
Requests实践详解&& python通过连接开启https的elasticsearch7 服务器
查看>>
ES查询流程源码解析
查看>>
ldaps与ldap over TLS
查看>>
jvm为什么把-Xms和-Xmx的值设置成一样
查看>>