标签:roo 定义 int check name 表示 line mba void
struct point { int x[DIM]; //DIM?维度 x表示一个k维向量 bool operator < (const point X) const { return x[now]<X.x[now]; } /* 考虑分割一个维度时,为了让分割更均匀,要尽量选最中间的点 now表示当前维护维度,定义小于号来维护中间的点。*/ }// 存储一个向量 struct node { int l,r;//左右子树 int sze;//子树大小 int minn[DIM];//此节点维护的空间中第i维的最小值 int maxx[DIM];//此节点维护的空间中第i维的最大值 point data;//这个点所维护的向量 }//KD-tree上一个节点的定义
void update(int pos) { for(int i=0;i<DEM;i++) { tree[pos].maxx[i]=tree[pos].minn[i]=tree[pos].data.x[i]; if(tree[pos].l) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].l].minn[i]); if(tree[pos].r) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].r].minn[i]); if(tree[pos].l) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].l].maxx[i]); if(tree[pos].r) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].r].maxx[i]); } tree[pos].sze=tree[tree[pos].l].sze+tree[tree[pos].r].sze+1; }/*就是字面意思,维护子树大小,维护其子树中能到达某一维度的最大值,最小值。*/
void update(int pos) { for(int i=0;i<DEM;i++) { tree[pos].maxx[i]=tree[pos].minn[i]=tree[pos].data.x[i]; if(tree[pos].l) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].l].minn[i]); if(tree[pos].r) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].r].minn[i]); if(tree[pos].l) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].l].maxx[i]); if(tree[pos].r) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].r].maxx[i]); } tree[pos].sze=tree[tree[pos].l].sze+tree[tree[pos].r].sze+1; }/*就是字面意思,维护子树大小,维护其子树中能到达某一维度的最大值,最小值。*/
void update(int pos) { for(int i=0;i<DEM;i++) { tree[pos].maxx[i]=tree[pos].minn[i]=tree[pos].data.x[i]; if(tree[pos].l) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].l].minn[i]); if(tree[pos].r) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].r].minn[i]); if(tree[pos].l) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].l].maxx[i]); if(tree[pos].r) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].r].maxx[i]); } tree[pos].sze=tree[tree[pos].l].sze+tree[tree[pos].r].sze+1; }/*就是字面意思,维护子树大小,维护其子树中能到达某一维度的最大值,最小值。*/
void check(int& pos,int dim) { if(tree[pos].sze*alpha<tree[tree[pos].l].sze||tree[pos].sze*alpha<tree[tree[pos].r].sze) {rev(pos,0); pos=build(1,tree[pos].sze,dim);} }// 字面意思 不平衡就拍扁重建 , alpha是替罪羊的平衡因子
int insert(int pos,point data,int dim) { if(!pos) {pos=New(); tree[pos].l=tree[pos].r=0; tree[pos].data=data; update(pos); return pos;} if(data.x[dim]<=tree[pos].data.x[dem]) tree[pos].l=insert(tree[pos].l,data,dim^1); else tree[pos].r=insert(tree[pos].r,data,dim^1); update(pos); check(pos,dim); return pos; }//像平衡树一样左右看看加那边,然后挂上节点。最后check一下不让树退化
void query(int pos,point data) { ans=min(ans,dist(data,tree[pos].data)); //用当前点信息更新ans int dist_left=INF; int dist_right=INF; if(tree[pos].l) dist_left=get_dist(data,tree[pos].l); if(tree[pos].r) dist_right=get_dist(data,tree[pos].r); // L,R维护是查询点s到当前点左右子树所维护空间的距离 if(dist_left<dist_right) { if(dist_left<ans) query(tree[pos].l,data); if(dist_right<ans) query(tree[pos].r,data); } else { if(dist_right<ans) query(tree[pos].r,data); if(dist_left<ans) query(tree[pos].l,data); } // 以当前点为圆心,以ans为半径画圆,如果达不到左/右子树所维护的空间,就不查那边。 }
#include<bits/stdc++.h> #define DEM 2 #define alpha (1.130/2) #define maxn 1000010 #define INF 0x3f3f3f3f using namespace std; int n,m; int u,v; int now; int ans; int opt; int root; int points; queue<int>Q; struct point { int x[DEM]; bool operator < (const point X) const {return x[now]<X.x[now];} }one[maxn]; struct node { int l,r; int sze; int minn[DEM]; int maxx[DEM]; point data; }tree[maxn]; int dist(point,point); int get_dist(point,int); int New(); void update(int); void rev(int,int); int build(int,int,int); void check(int&,int); int insert(int,point,int); void query(int,point); int main() { cin>>n>>m; for(int i=1;i<=n;i++) cin>>one[i].x[0]>>one[i].x[1]; root=build(1,n,0); for(int i=1;i<=m;i++) { cin>>opt>>u>>v; if(opt==1) {root=insert(root,(point){u,v},0);} else {ans=INF; query(root,(point){u,v}); cout<<ans<<endl;} } } int dist(point A,point B) {return abs(A.x[0]-B.x[0])+abs(A.x[1]-B.x[1]);} int get_dist(point A,int pos) {int ret=0; for(int i=0;i<DEM;i++) ret+=max(0,A.x[i]-tree[pos].maxx[i])+max(0,tree[pos].minn[i]-A.x[i]); return ret;} int New() { if(!Q.empty()) {static int tmp; tmp=Q.front(); Q.pop(); return tmp;} else return ++points; } void update(int pos) { for(int i=0;i<DEM;i++) { tree[pos].maxx[i]=tree[pos].minn[i]=tree[pos].data.x[i]; if(tree[pos].l) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].l].minn[i]); if(tree[pos].r) tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].r].minn[i]); if(tree[pos].l) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].l].maxx[i]); if(tree[pos].r) tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].r].maxx[i]); } tree[pos].sze=tree[tree[pos].l].sze+tree[tree[pos].r].sze+1; } void rev(int pos,int num) { if(tree[pos].l) rev(tree[pos].l,num); one[tree[tree[pos].l].sze+num+1]=tree[pos].data; Q.push(pos); if(tree[pos].r) rev(tree[pos].r,tree[tree[pos].l].sze+num+1); } int build(int l,int r,int dem) { if(l>r) return 0; int mid=(l+r)>>1,pos=New(); now=dem; nth_element(one+l,one+mid,one+r+1); tree[pos].data=one[mid]; tree[pos].l=build(l,mid-1,dem^1); tree[pos].r=build(mid+1,r,dem^1); update(pos); return pos; } void check(int& pos,int dem) { if(tree[pos].sze*alpha<tree[tree[pos].l].sze||tree[pos].sze*alpha<tree[tree[pos].r].sze) {rev(pos,0); pos=build(1,tree[pos].sze,dem);} } int insert(int pos,point data,int dem) { if(!pos) {pos=New(); tree[pos].l=tree[pos].r=0; tree[pos].data=data; update(pos); return pos;} if(data.x[dem]<=tree[pos].data.x[dem]) tree[pos].l=insert(tree[pos].l,data,dem^1); else tree[pos].r=insert(tree[pos].r,data,dem^1); update(pos); check(pos,dem); return pos; } void query(int pos,point data) { ans=min(ans,dist(data,tree[pos].data)); int dist_left=INF; int dist_right=INF; if(tree[pos].l) dist_left=get_dist(data,tree[pos].l); if(tree[pos].r) dist_right=get_dist(data,tree[pos].r); if(dist_left<dist_right) { if(dist_left<ans) query(tree[pos].l,data); if(dist_right<ans) query(tree[pos].r,data); } else { if(dist_right<ans) query(tree[pos].r,data); if(dist_left<ans) query(tree[pos].l,data); } }
标签:roo 定义 int check name 表示 line mba void
原文地址:https://www.cnblogs.com/simba351/p/11504169.html