【kd-tree】bzoj3290 Theresa与数据结构
离线所有操作,对所有可能存在的点建立kd-tree,add相当于权值+1,cancel相当于权值-1。
修改操作要记录kd-tree上每个点的fa,从底向上地进行修改。
优化:若一个矩形框的sumv==0,则不进入。记录矩形框的面积时只记录“有意义”的点的(权值为0的不管)。
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cstring>
using namespace std;
int f,C;
inline void R(int &x){
C=0;f=1;
for(;C<'0'||C>'9';C=getchar())if(C=='-')f=-1;
for(x=0;C>='0'&&C<='9';C=getchar())(x*=10)+=(C-'0');
x*=f;
}
inline void P(int x){
if(x<10)putchar(x+'0');
else{P(x/10);putchar(x%10+'0');}
}
stack<int>zhan;
#define N 100001
#define KD 3
int dn,n,root,m,qp[2][KD],idn;
struct Node
{
int ch[2],w,minn[KD],maxx[KD],p[KD],sumv,id;
void Init()
{
sumv=w;
for(int i=0;i<KD;++i)
minn[i]=maxx[i]=p[i];
}
}T[N];
bool operator < (const Node &a,const Node &b){return a.p[dn] < b.p[dn];}
inline void pushup(const int &rt)
{
T[rt].sumv=T[rt].w;
for(int i=0;i<2;++i)
if(T[rt].ch[i]/* && T[T[rt].ch[i]].sumv*/)
{
T[rt].sumv+=T[T[rt].ch[i]].sumv;
for(int j=0;j<KD;++j)
{
T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
}
}
}
int buildtree(int l=1,int r=n,int d=0)
{
dn=d;
int m=(l+r>>1);
nth_element(T+l,T+m,T+r+1);
T[m].Init();
if(l!=m) T[m].ch[0]=buildtree(l,m-1,(d+1)%KD);
if(m!=r) T[m].ch[1]=buildtree(m+1,r,(d+1)%KD);
pushup(m);
return m;
}
inline bool Inside(const int &o)
{
for(int i=0;i<KD;++i)
if(qp[0][i] > T[o].p[i] || T[o].p[i] > qp[1][i])
return 0;
return 1;
}
inline bool AllInside(const int &o)
{
for(int i=0;i<KD;++i)
if(qp[0][i] > T[o].minn[i] || T[o].maxx[i] > qp[1][i])
return 0;
return 1;
}
inline bool Cross(const int &o)
{
for(int i=0;i<KD;++i)
if(qp[0][i] > T[o].maxx[i] || T[o].minn[i] > qp[1][i])
return 0;
return 1;
}
int ans;
inline void Query(int rt=root)
{
if(Inside(rt)) ans+=T[rt].w;
for(int i=0;i<2;++i)
if(T[rt].ch[i] && Cross(T[rt].ch[i]))
{
if(AllInside(T[rt].ch[i]))
ans+=T[T[rt].ch[i]].sumv;
else if(T[T[rt].ch[i]].sumv)
Query(T[rt].ch[i]);
}
}
int val;
char op[N][7];
int dian[N][KD],rs[N],ids[N],ma[N],fa[N];
void Update()
{
int U=ma[idn];
T[U].w+=val;
T[U].sumv+=val;
U=fa[U];
while(U)
{
T[U].sumv=T[U].w+T[T[U].ch[0]].sumv+T[T[U].ch[1]].sumv;
// pushup(U);
U=fa[U];
}
}
int main()
{
// freopen("theresa9.in","r",stdin);
// freopen("bzoj3290.out","w",stdout);
R(n);
for(int i=1;i<=n;++i)
{
R(T[i].p[0]); R(T[i].p[1]); R(T[i].p[2]);
T[i].id=i;
T[i].w=1;
}
R(m);
for(int i=1;i<=m;++i)
{
scanf("%s",op[i]);
if(op[i][0]=='A')
{
++n;
R(T[n].p[0]); R(T[n].p[1]); R(T[n].p[2]);
T[n].id=n;
ids[i]=n;
zhan.push(n);
}
else if(op[i][0]=='Q')
{
R(dian[i][0]); R(dian[i][1]); R(dian[i][2]); R(rs[i]);
}
else
{
ids[i]=zhan.top();
zhan.pop();
}
}
root=(1+n>>1);
buildtree();
for(int i=1;i<=n;++i)
{
ma[T[i].id]=i;
for(int j=0;j<2;++j)
if(T[i].ch[j])
fa[T[i].ch[j]]=i;
}
for(int i=1;i<=m;++i)
if(op[i][0]=='A')
{
idn=ids[i];
val=1;
Update();
}
else if(op[i][0]=='Q')
{
memcpy(qp[0],dian[i],sizeof(qp[0]));
for(int j=0;j<KD;++j)
qp[1][j]=qp[0][j]+rs[i];
ans=0;
Query();
// printf("%d\n",ans);
P(ans),puts("");
}
else
{
idn=ids[i];
val=-1;
Update();
}
return 0;
}
【kd-tree】bzoj3290 Theresa与数据结构的更多相关文章
- BZOJ3290 : Theresa与数据结构
CANCEL操作可以看作删点,X坐标可以离散化 将询问按Z坐标差分,转化成两个求Z<=某个数的和的询问 将操作CDQ分治 每次将前一半的修改.后一半的查询按照Z坐标排序 然后扫描线,每到一个询问 ...
- 【数据结构与算法】k-d tree算法
k-d tree算法 k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点 ...
- 【数据结构】K-D Tree
K-D Tree 这东西是我入坑 ICPC 不久就听说过的数据结构,但是一直没去学 QAQ,终于在昨天去学了它.还是挺好理解的,而且也有用武之地. 目录 简介 建树过程 性质 操作 例题 简介 K-D ...
- 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree
2648: SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2459 Solved: 834[Submit][Status][Discu ...
- k-d tree算法
k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...
- HDU2966 In case of failure(浅谈k-d tree)
嘟嘟嘟 题意:给定\(n\)个二维平面上的点\((x_i, y_i)\),求离每一个点最近的点得距离的平方.(\(n \leqslant 1e5\)) 这就是k-d tree入门题了. k-d tre ...
- 浅谈K-D Tree
初步认识\(K-D\) \(Tree\) \(K-D\) \(Tree\)是一种基于空间分割的二叉树形数据结构,一般用于高维信息检索.因为\(OI\)中很多问题都能转化为高维信息检索,所以\(K-D\ ...
- [转载]kd tree
[本文转自]http://www.cnblogs.com/eyeszjwang/articles/2429382.html k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据 ...
- 初涉k-d tree
听说k-d tree是一个骗分的好东西?(但是复杂度差评??? 还听说绍一的kdt常数特别小? KDT是什么 KDT的全称是k-degree tree,顾名思义,这是一种处理多维空间的数据结构. 例如 ...
随机推荐
- POJ 3179 Corral the Cows
Corral the Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1352 Accepted: 565 De ...
- There is an overlap in the region chain
ERROR: (regions day_hotstatic,860010-2355010000_20140417_12_entry_00000000321,1398674475358.0dc20573 ...
- vue相对路径修改
如果静态文件不是部署在网站根目录下,vue-cli将给你造成巨大的麻烦. 你不能直接把build好的文件抛进一个目录.你不能直接在本地打开用vue做好的静态网站. 改成相对路径,主要需要做两步. 1. ...
- CSS3奇偶选择器
.search-form td:nth-child(odd){//奇 width:100px; text-align:right;} .search-form td:nth-child(even){/ ...
- ACM-ICPC 2018 南京赛区网络预赛 Sum
A square-free integer is an integer which is indivisible by any square number except 11. For example ...
- 知问前端——工具提示UI
工具提示(tooltip),是一个非常实用的UI.它彻底扩展了HTML中的title属性,让提示更加丰富,更加可控制,全面提升了用户体验. 调用tooltip()方法 在调用tooltip()方法之前 ...
- bzoj 1150 贪心
首先选取的线段一定是相邻两个端点线段,那么我们贪心的考虑这个问题,我们先在这n-1条线段中选出最短的一条,然后将这条线段的值改为左面的线段的值+右面的线段的值-自己的值,用这条线段取代原来这三条线段, ...
- Iframe跨域嵌入页面自动调整高度的办法
http://www.a.com/A.html http://www.a.com/B.html http://www.a.com/D.js http://www.c.com/C.html A.html ...
- Python学习笔记 - day5 - 文件操作
Python文件操作 读写文件是最常见的IO操作,在磁盘上读写文件的功能都是由操作系统提供的,操作系统不允许普通的程序直接操作磁盘(大部分程序都需要间接的通过操作系统来完成对硬件的操作),所以,读写文 ...
- shell脚本之while for if 语句和编写计划任务
关于while循环: while do done 例如 1.关于内存的实时操作: (1).vim a.sh (2).输入以下while循环 (3)../a.sh执行脚本 2.自加一的操作: (1).v ...