KDT
解决多维偏序问题
k 维轮流排序
需要维护什么
对于板子
maxn[2] minn[2] 这个点代表的矩形边界
sum 值
siz 这个点代表的矩形里有多少个数
node{int x[2],a;} 这个点的坐标,值
ls rs 儿子
insert
void insert(int &k,node pp,int w){
if(!k){k=newnode();tree[k].ls=tree[k].rs=0;tree[k].tp=pp;pushup(k);return;}
if(tree[k].tp.x[w]>=pp.x[w])insert(tree[k].ls,pp,w^1);
else insert(tree[k].rs,pp,w^1);
pushup(k),check(k,w);
}
pushup
void pushup(int k){
int l=tree[k].ls,r=tree[k].rs;
for(int i=0;i<=1;i++){
tree[k].minn[i]=tree[k].maxn[i]=tree[k].tp.x[i];
if(l){
tree[k].minn[i]=min(tree[k].minn[i],tree[l].minn[i]);
tree[k].maxn[i]=max(tree[k].maxn[i],tree[l].maxn[i]);
}
if(r){
tree[k].minn[i]=min(tree[k].minn[i],tree[r].minn[i]);
tree[k].maxn[i]=max(tree[k].maxn[i],tree[r].maxn[i]);
}
}
tree[k].sum=tree[l].sum+tree[k].tp.a+tree[r].sum,tree[k].siz=tree[l].siz+1+tree[r].siz;
}
query
int query(int k,int x1,int y1,int x2,int y2){
if(!k)return 0;
int res=0;
if(in(x1,y1,x2,y2,tree[k].minn[0],tree[k].minn[1],tree[k].maxn[0],tree[k].maxn[1]))return tree[k].sum;
if(out(x1,y1,x2,y2,tree[k].minn[0],tree[k].minn[1],tree[k].maxn[0],tree[k].maxn[1]))return 0;
if(in(x1,y1,x2,y2,tree[k].tp.x[0],tree[k].tp.x[1],tree[k].tp.x[0],tree[k].tp.x[1]))res+=tree[k].tp.a;
res+=query(tree[k].ls,x1,y1,x2,y2)+query(tree[k].rs,x1,y1,x2,y2);
return res;
}
重构
int operator <(node a,node b){return a.x[W]<b.x[W];}
int build(int l,int r,int w){
if(l>r)return 0;
int mid=(l+r)>>1,k=newnode();
W=w;nth_element(p+l,p+mid,p+r+1),tree[k].tp=p[mid];
tree[k].ls=build(l,mid-1,w^1),tree[k].rs=build(mid+1,r,w^1);
pushup(k);return k;
}
void pia(int k,int num){
if(tree[k].ls)pia(tree[k].ls,num);
p[tree[tree[k].ls].siz+1+num]=tree[k].tp;
st[++top]=k;
if(tree[k].rs)pia(tree[k].rs,num+tree[tree[k].ls].siz+1);
}
void check(int &k,int w){
if(tree[k].siz*0.75<tree[tree[k].ls].siz||tree[k].siz*0.75<tree[tree[k].rs].siz){
pia(k,0),k=build(1,tree[k].siz,w);
}
}
原来的疑问,这里重构的时候没改他的 fa 的 ls 啊
注意 &

浙公网安备 33010602011771号