题目

平面上有 \(N\) 个点。需要实现以下三种操作:

  1. 在点集里添加一个点;

  2. 给出一个点,查询它到点集里所有点的曼哈顿距离的最小值;

  3. 给出一个点,查询它到点集里所有点的曼哈顿距离的最大值。


分析

用KD-Tree实现,维护区间横纵坐标最小值和最大值,

由于需要在点集中添加点,可能会导致K-D Tree树高不平衡,

那么直接用替罪羊树拍扁重建即可


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <queue>
#define rr register
using namespace std;
const int N=200011;
typedef long long lll;
const double alp=0.75;
int ran,root,n,m,ans;
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
struct rec{
int p[2];
bool operator <(const rec &t)const{
return p[ran]<t.p[ran];
}
};
inline signed Abs(int x){return x<0?-x:x;}
struct KD_Tree{
int mn[N][2],mx[N][2],son[N][2],siz[N],stac[N],TOP,tot; rec pt[N],p[N];
inline void pup(int now){
for (rr int i=0;i<2;++i){
mn[now][i]=mx[now][i]=p[now].p[i];
if (son[now][0]){
mn[now][i]=min(mn[now][i],mn[son[now][0]][i]);
mx[now][i]=max(mx[now][i],mx[son[now][0]][i]);
}
if (son[now][1]){
mn[now][i]=min(mn[now][i],mn[son[now][1]][i]);
mx[now][i]=max(mx[now][i],mx[son[now][1]][i]);
}
}
siz[now]=siz[son[now][0]]+siz[son[now][1]]+1;
}
inline bool balance(int now){return alp*siz[now]>=(max(siz[son[now][0]],siz[son[now][1]]));}
inline void recycle(int now){
if (son[now][0]) recycle(son[now][0]);
stac[++TOP]=now,pt[TOP]=p[now];
if (son[now][1]) recycle(son[now][1]);
}
inline signed build(int l,int r,int Ran){
if (l>r) return 0;
rr int mid=(l+r)>>1,now=stac[mid];
ran=Ran,nth_element(pt+l,pt+mid,pt+1+r),p[now]=pt[mid];
son[now][0]=build(l,mid-1,Ran^1);
son[now][1]=build(mid+1,r,Ran^1);
pup(now);
return now;
}
inline void rebuild(int &now,int Ran){
TOP=0,recycle(now);
now=build(1,TOP,Ran);
}
inline void Insert(int &now,rec W,int Ran){
if (!now) now=++tot,p[now]=W;
else{
if (W.p[Ran]<=p[now].p[Ran]) Insert(son[now][0],W,Ran^1);
else Insert(son[now][1],W,Ran^1);
}
pup(now);
if (!balance(now)) rebuild(now,Ran);
}
inline signed calcmn(int t,int x){
rr int ans=0;
for (rr int i=0;i<2;++i) ans+=max(mn[t][i]-p[x].p[i],0)+max(p[x].p[i]-mx[t][i],0);
return ans;
}
inline signed calcmx(int t,int x){
return max(Abs(p[x].p[0]-mn[t][0]),Abs(p[x].p[0]-mx[t][0]))+max(Abs(p[x].p[1]-mn[t][1]),Abs(p[x].p[1]-mx[t][1]));
}
inline void querymn(int now,int x){
rr int t=Abs(p[x].p[0]-p[now].p[0])+Abs(p[x].p[1]-p[now].p[1]);
if (ans>t) ans=t;
rr int c0=calcmn(son[now][0],x),c1=calcmn(son[now][1],x);
if (son[now][0]&&son[now][1]){
if (c0<c1&&c0<ans){
querymn(son[now][0],x);
if (c1<ans) querymn(son[now][1],x);
}else if (c1<ans){
querymn(son[now][1],x);
if (c0<ans) querymn(son[now][0],x);
}
}else if (son[now][0]){
if (c0<ans) querymn(son[now][0],x);
}else if (son[now][1]){
if (c1<ans) querymn(son[now][1],x);
}
}
inline void querymx(int now,int x){
rr int t=Abs(p[x].p[0]-p[now].p[0])+Abs(p[x].p[1]-p[now].p[1]);
if (ans<t) ans=t;
rr int c0=calcmx(son[now][0],x),c1=calcmx(son[now][1],x);
if (son[now][0]&&son[now][1]){
if (c0>c1&&c0>ans){
querymx(son[now][0],x);
if (c1>ans) querymx(son[now][1],x);
}else if (c1>ans){
querymx(son[now][1],x);
if (c0>ans) querymx(son[now][0],x);
}
}else if (son[now][0]){
if (c0>ans) querymx(son[now][0],x);
}else if (son[now][1]){
if (c1>ans) querymx(son[now][1],x);
}
}
}Tre;
signed main(){
n=iut();
for (rr int i=1;i<=n;++i) Tre.Insert(root,(rec){iut(),iut()},0);
for (rr int m=iut();m;--m){
rr int opt=iut(),x,y;
Tre.p[Tre.tot+1].p[0]=x=iut();
Tre.p[Tre.tot+1].p[1]=y=iut();
if (opt==0) Tre.Insert(root,(rec){x,y},0);
else if (opt==1) ans=0x3f3f3f3f,Tre.querymn(root,Tre.tot+1),print(ans),putchar(10);
else ans=-0x3f3f3f3f,Tre.querymx(root,Tre.tot+1),print(ans),putchar(10);
}
return 0;
}

#KD-Tree,替罪羊树#洛谷 6224 [BJWC2014]数据的更多相关文章

  1. AC日记——校门外的树 洛谷 P1047

    题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种 ...

  2. 线段树 洛谷P3932 浮游大陆的68号岛

    P3932 浮游大陆的68号岛 题目描述 妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活. 换用更高尚的说法,是随时准备着为这个无药可救的世界献身. 然而孩子们的生活却总是无忧无 ...

  3. [线段树]洛谷P5278 算术天才⑨与等差数列

    题目描述 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k ...

  4. 带修主席树 洛谷2617 支持单点更新以及区间kth大查询

    题目链接:https://www.luogu.com.cn/problem/P2617 参考博客:https://blog.csdn.net/dreaming__ldx/article/details ...

  5. 区间连续长度的线段树——洛谷P2894 [USACO08FEB]酒店Hotel

    https://www.luogu.org/problem/P2894 #include<cstdio> #include<iostream> using namespace ...

  6. Solution -「APIO/CTSC 2007」「洛谷 P3620」数据备份

    \(\mathcal{Description}\)   Link.   给定升序序列 \(\{x_n\}\) 以及整数 \(k\),在 \(\{x_n\}\) 中选出恰 \(k\) 对 \((x_i, ...

  7. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  8. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  9. [洛谷P1198/BZOJ1012][JSOI2008] 最大数 - 树状数组/线段树?

    其实已经学了树状数组和线段树,然而懒得做题,所以至今没写多少博客 Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数 ...

  10. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

随机推荐

  1. Java缓存框架整理

    Spring Cache 为基于Spring框架的应用提供了一套完整的缓存API抽象,具体的缓存实现可以对接如Ehcache,Redis等. https://docs.spring.io/spring ...

  2. Vue3学习(十八) - TreeSelect 树选择

    写在前面 本以为可以在家学习一天,结果家里来了客人拜年,就没学习上,有点小遗憾吧. 昨天完成从分类管理的前后端代码复制出文档管理的前后端代码,遗留问题是只能选择一级父分类.值得说的是,昨晚的遗留的问题 ...

  3. Unity学习笔记--数据持久化Json

    JSON相关 json是国际通用语言,可以跨平台(游戏,软件,网页,不同OS)使用, json语法较为简单,使用更广泛.json使用键值对来存储. 认识json文件 //注意字典类型存储时,键是以st ...

  4. DataGear 制作基于Vue2、Element UI前端框架的数据可视化看板

    DataGear 数据可视化看板内置了一些基本.简单的页面交互组件,当它们无法满足实际看板需求时,可以引入更流行和强大的前端框架. 本文以Vue2.Element UI前端框架为例,介绍如何制作具有更 ...

  5. 【Azure 事件中心】Event Hubs如何获取其中存放的历史消息

    问题描述 使用Azure Event Hub服务,除了正常的生产,消费消息以外,如果想拿到Event Hub中存储的历史消息?有什么方法呢? 问题解答 获取 Event Hubs 存储的历史消息,首先 ...

  6. C#的Winform程序关于单击和双击的区别 - 开源研究系列文章

    前些天编码的时候有个关于应用程序的托盘图标的鼠标Mouse Down里的单击和双击的问题,只是想单击的时候显示主窗体,双击的时候显示操作窗体.但是编码并调试的时候发现Windows的鼠标双击的事件先执 ...

  7. OPPO 自研大规模知识图谱及其在数智工程中的应用

    导读:OPPO 知识图谱是 OPPO 数智工程系统小布助手团队主导.多团队协作建设的自研大规模通用知识图谱,目前已达到数亿实体和数十亿三元组的规模,主要落地在小布助手知识问答.电商搜索等场景. 本文主 ...

  8. STL-RBT_map,set模拟实现

    set #include"26RBT_container.h" namespace test { //set通过普通迭代器使用const迭代器实现限制key不能被修改 templa ...

  9. UI自动化测试中图片验证码的处理?

    首先定位验证码image的元素,然后通过element.screenshot('a.png')截图保存到本地,通过第三方接口识别本地图片验证码

  10. nginx设置访问账号密码

    第一:为kibana加上了用户登陆访问 第二:不暴露服务器上5601端口,只开放80端口即可.这对服务器的安全也是一个很大的保护. 接下来我们就开始配置nginx与kibana. 一.配置nginx ...