====== 前言 ====== 用处与一维线段树类似,实现区间的修改、查询工作,知识是在二维的区域中实现的。 ====== 两种实现方式 ====== * 普通列表项目每一个节点代表一颗线段树 {{:2020-2021:teams:no_morning_training:shaco:知识点:数据结构:0.5935530263444292.png?200|}} * 普通列表项目四分法转为一维线段树 {{:2020-2021:teams:no_morning_training:shaco:知识点:数据结构:0.7330317843697223.png?200|}} ====== 复杂度 ====== 空间复杂度都是$O(n^2\times log_n^2)$。 第一种方法单次操作时间复杂度为$O(log_n^2)$,第二种方法最差可以退化到$O(n)$。 这里介绍第一种方法。思想主要是在二维的区间中将包含目标小区间的区间全部修改,类似于一维情况。 ====== 操作 ====== ===== 单点修改+矩阵查询 ===== ==== 修改 ==== void changex(int kx,int l,int r) { changey(kx,1,1,h); if(l==r) return; int mid=l+r>>1; if(x<=mid) changex(kx<<1,l,mid); else changex(kx<<1|1,mid+1,r); } void changey(int kx,int ky,int l,int r) //方法一 { sum[kx][ky]++; if(l==r) return; int mid=l+r>>1; if(y<=mid) changey(kx,ky<<1,l,mid); else changey(kx,ky<<1|1,mid+1,r); } void changey(int kx,int ky,int l,int r) //方法二 { if(l==r) { sum[kx][ky]++; return; } int mid=l+r>>1; if(y<=mid) changey(kx,ky<<1,l,mid); else changey(kx,ky<<1|1,mid+1,r); sum[kx][ky]=sum[kx][ky<<1]+sum[kx][ky<<1|1]; } ==== 查询 ==== void queryy(int kx,int ky,int l,int r) { if(l>=yl && r<=yr) { cnt+=sum[kx][ky]; return; } int mid=l+r>>1; if(yl<=mid) queryy(kx,ky<<1,l,mid); if(yr>mid) queryy(kx,ky<<1|1,mid+1,r); } void queryx(int kx,int l,int r) { if(l>=xl && r<=xr) { queryy(kx,1,1,h); return; } int mid=l+r>>1; if(xl<=mid) queryx(kx<<1,l,mid); if(xr>mid) queryx(kx<<1|1,mid+1,r); } ===== 矩阵修改+单点查询 ===== ==== 修改 ==== void changey(int kx,int ky,int l,int r) { if(y1<=l&&r<=y2) { sum[kx][ky]++; return; } int mid=l+r>>1; if(y1<=mid) changey(kx,ky<<1,l,mid); if(y2>mid) changey(kx,ky<<1|1,mid+1,r); } void changex(int kx,int l,int r) { if(x1<=l&&r<=x2) { changey(kx,1,1,n); return; } int mid=l+r>>1; if(x1<=mid) changex(kx<<1,l,mid); if(x2>mid) changex(kx<<1|1,mid+1,r); } ==== 查询 ==== void queryy(int kx,int ky,int l,int r) { ans+=sum[kx][ky]; if(l==r) return; int mid=ly+ry>>1; if(y<=mid) queryy(kx,ky<<1,l,mid); else queryy(kx,ky<<1|1,mid+1,r); } void queryx(int kx,int l,int r) { queryy(kx,1,1,n); if(l==r) return; int mid=l+r>>1; if(x<=mid) queryx(kx<<1,l,mid); else queryx(kx<<1|1,mid+1,r); } ====== 参考 ====== [[https://www.cnblogs.com/TheRoadToTheGold/p/8151375.html]]