KDT总结
咕咕咕。
学会了一点了。
KDT维护了
KDT的实现与平衡树类似(其实在
还有类似线段树写法,用叶子存信息再向上合并的,但我只写过平衡树写法的。
建树时交替选择nth_element
,这一步是
插入结点可以二进制分组。具体而言,保证维护的KDT的大小都为
删除可以打标记惰性删除,然后根号/替罪羊重构。
每个结点维护每个维度的最大值与最小值,然后查询随便写一下就好(二进制分组的写法要在每棵树上都查一下)。
建树
OI中
而当
为数不多还在坚持KDT的KDT板子题P4148 简单题。
板子
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10,mxlg=19;
int n,cnt,lst,b[maxn],rt[mxlg],lim[2][2];
struct TREE{
int x[2],v,sum,ls,rs,l[2],r[2];
}t[maxn];
bool cmp0(int a,int b){
return t[a].x[0]<t[b].x[0];
}
bool cmp1(int a,int b){
return t[a].x[1]<t[b].x[1];
}
#define ls(k) (t[k].ls)
#define rs(k) (t[k].rs)
void pushup(int k){
t[k].sum=t[k].v+t[ls(k)].sum+t[rs(k)].sum;
for(int i=0;i<2;++i){
t[k].l[i]=t[k].r[i]=t[k].x[i];
if(ls(k)){
t[k].l[i]=min(t[k].l[i],t[ls(k)].l[i]);
t[k].r[i]=max(t[k].r[i],t[ls(k)].r[i]);
}
if(rs(k)){
t[k].l[i]=min(t[k].l[i],t[rs(k)].l[i]);
t[k].r[i]=max(t[k].r[i],t[rs(k)].r[i]);
}
}
}
int build(int l,int r,int k){
int p=(l+r)>>1;
if(k) nth_element(b+l,b+p,b+r+1,cmp1);
else nth_element(b+l,b+p,b+r+1,cmp0);
int x=b[p];
if(l<p) t[x].ls=build(l,p-1,k^1);
if(p<r) t[x].rs=build(p+1,r,k^1);
pushup(x);
return x;
}
void flatten(int &p){
if(!p) return;
b[++cnt]=p;
flatten(ls(p));
flatten(rs(p));
p=0;
}
int qry(int p){
if(!p) return 0;
bool flag=true;
for(int k=0;k<2;++k) flag&=(lim[k][0]<=t[p].l[k]&&t[p].r[k]<=lim[k][1]);
if(flag) return t[p].sum;
for(int k=0;k<2;++k){
if(t[p].l[k]>lim[k][1]||t[p].r[k]<lim[k][0]) return 0;
}
int rs=0;
flag=true;
for(int k=0;k<2;++k) flag&=(lim[k][0]<=t[p].x[k]&&t[p].x[k]<=lim[k][1]);
if(flag) rs=t[p].v;
return rs+=qry(ls(p))+qry(rs(p));
}
int main(){
scanf("%d",&n);
n=0;
while(true){
int op;
scanf("%d",&op);
if(op==3) break;
else if(op==1){
int x,y,a;
scanf("%d%d%d",&x,&y,&a);
x^=lst;
y^=lst;
a^=lst;
t[++n].x[0]=x;
t[n].x[1]=y;
t[n].v=a;
cnt=1;
b[1]=n;
for(int sz=0;;sz++){
if(!rt[sz]){
rt[sz]=build(1,cnt,0);
break;
}
else flatten(rt[sz]);
}
}
else if(op==2){
scanf("%d%d%d%d",&lim[0][0],&lim[1][0],&lim[0][1],&lim[1][1]);
lim[0][0]^=lst;
lim[0][1]^=lst;
lim[1][0]^=lst;
lim[1][1]^=lst;
lst=0;
for(int i=0;i<mxlg;++i) lst+=qry(rt[i]);
printf("%d\n",lst);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)