段树2D,矩形之和
Segment tree 2D, sum of rectangle
我真的很想学习并实现段树2D。它一直困扰着我。我知道分段树的1D情况,但不知怎么的,我无法处理2D。问题是我有一个矩阵1024x1024(所以我使用一个数组[2048][2048]作为树),我想实现两个操作:
- 无效插入(int x,int y,int val);-它将值val分配给矩阵的元素[x][y]
- int查询(int x1,int y1,int x2,int y2);-返回矩形(x1,y1,x2,y2)中矩阵中元素的总和
到目前为止,我写的是:
const int M=1024;
int tree[2*M][2*M];
void insert(int x, int y, int val) {
int vx=M+x, vy=M+y;
tree[vx][vy]=val;
while(vy!=1) {
vy/=2;
tree[vx][vy]=tree[vx][2*vy]+tree[vx][2*vy+1];
}
while(vx!=1) {
vy=M+y;
vx/=2;
while(vy!=1) {
vy/=2;
tree[vx][vy]=tree[2*vx][2*vy]+tree[2*vx+1][2*vy+1];
}
}
}
int query(int x1, int y1, int x2, int y2) {
int vx1=M+x1, vy1=M+y1, vx2=M+x2, vy2=M+y2;
int res=tree[vx1][vy1];
if(vx1!=vx2 || vy1!=vy2) res+=tree[vx2][vy2];
while(vx1/2 != vx2/2) {
vy1=M+y1; vy2=M+y2;
while(vy1/2 != vy2/2) {
if(vx1%2==0 && vy1%2==0) res+=tree[vx1+1][vy1+1];
if(vx2%2==1 && vy2%2==1) res+=tree[vx2-1][vy2-1];
vy1/=2; vy2/=2;
}
vx1/=2; vx2/=2;
}
return res;
}
但它不能正常工作。例如:
插入(5,5,1);查询(0,51000,5);
它返回0,而不是1。我认为问题出在查询中(我希望插入可以),我不完全理解这个操作的想法。在1D中,我没有遇到任何问题,但这种情况对我来说很难想象
你能帮我正确地执行吗?如果能得到帮助,我将不胜感激。
编辑:也许展示我如何在1D中做到这一点会更好,这段代码很有效,我认为想法很简单:
const int M=1024;
int tree[2*M];
void insert(int x, int val) {
int v=M+x;
tree[v]=val;
while(v!=1) {
v/=2;
tree[v]=tree[2*v]+tree[2*v+1];
}
}
int query(int a, int b) {
int va=M+a, vb=M+b;
int res=tree[va];
if(va!=vb) res+=tree[vb];
while(va/2 != vb/2) {
if(va%2==0) res+=tree[va+1];
if(vb%2==1) res+=tree[vb-1];
va/=2; vb/=2;
}
return res;
}
但不幸的是,我无法在2D中应用它。。
好吧,您的案例之所以返回0,是因为只有这部分代码被执行:
int res=tree[vx1][vy1];
if(vx1!=vx2 || vy1!=vy2)
res+=tree[vx2][vy2];
这里,res
是0,因为在您的情况下,tree[vx1][vy1]
和tree[vx2][vy2]
都是零。
这部分不会改变res,因为条件从未满足:
if(vx1%2==0 && vy1%2==0)
res+=tree[vx1+1][vy1+1];
if(vx2%2==1 && vy2%2==1)
res+=tree[vx2-1][vy2-1];
因此,res值不会改变,仍然为0。
现在,关于整件事。你正在以一种非常奇怪的方式构建一个分段树,实际上,你根本没有构建任何树,而且有点难以理解你在用代码做什么。通常,您希望将二叉树(即分段树)实现为具有如下节点的链表:
struct node
{
int data;
node *left;
node *right;
};
我可以建议您在这里、这里、这里和这里查看二进制树和区间树的信息和实现。
相关文章:
- 我试图用这段代码找到二叉树的高度,但它一直返回 0,有人可以告诉我为什么吗?
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- c ++ 2d 数组和指向指针的指针 - 我不明白这段代码
- 如何从提升属性树中读取字段类型
- C++:段树中的运行时错误
- 矢量2D擦除元素并保持字段为空
- RMQ段树中的错误
- 为什么这段代码没有在二叉搜索树中插入节点
- Qt:如何制作一个2d插值颜色的字段
- 正在段树中查询
- 用于C++中的段树的STL
- 段树2D,矩形之和
- 段树的迭代代码
- 从 2D 数组中排除具有特定状态的字段;生命的游戏
- 如何使用段树计算数组中的反转次数
- C++中的二叉树段故障
- 段树实现中的问题
- 寻找最大使用段树给出错误的结果
- 实现2d范围树c++
- 内存分配错误-段树