二维线段树

#include<stdio.h>

#include<algorithm>

using namespace std;

#define LL(x)   (x<<1)

#define RR(x)  (x<<1|1)

 

struct Sub_Seg_Tree

{

    int  left,right,val;

    int mid() {return (left+right)/2;}

};

 

struct Seg_Tree

{

    int left,right;

    Sub_Seg_Tree tt[1001*3];

    int mid() {return (left+right)/2;}

}t[101*3];

 

void build2(Sub_Seg_Tree tt[],int l,int r,int idx)

{

    tt[idx].left=l;

    tt[idx].right=r;

    tt[idx].val=-1;//以便比较

    if(l==r)    return;

    int mid=tt[idx].mid();

    build2(tt,mid+1,r,RR(idx));

    build2(tt,l,mid,LL(idx));

}

 

void build(int l,int r,int idx)

{

    build2(t[idx].tt,0,1000,1);

    t[idx].left=l;

    t[idx].right=r;

    if(l==r)    return;

    int mid=t[idx].mid();

    build(mid+1,r,RR(idx));

    build(l,mid,LL(idx));

}

 

void update2(Sub_Seg_Tree tt[],int b,int val,int idx)

{

    if(tt[idx].left==tt[idx].right)

    {

        tt[idx].val=max(tt[idx].val,val);//可能有身高,活泼度相同的人

        return;

    }

    int mid=tt[idx].mid();

    if(mid<b)   update2(tt,b,val,RR(idx));

    if(mid>=b)  update2(tt,b,val,LL(idx));

    tt[idx].val=max(tt[RR(idx)].val,tt[LL(idx)].val);

}

 

void update(int a,int b,int val,int idx)

{

    update2(t[idx].tt,b,val,1);

    if(t[idx].left==t[idx].right) return;

    int mid=t[idx].mid();

    if(mid<a)  update(a,b,val,RR(idx));

    if(mid>=a)   update(a,b,val,LL(idx));

}

 

int query2(Sub_Seg_Tree tt[],int c,int d,int idx)

{

    if(tt[idx].left>=c&&tt[idx].right<=d)

    {

        return tt[idx].val;

    }

    int mid=tt[idx].mid();

    int res=-1;

    if(mid>=c)    res=max(res,query2(tt,c,d,LL(idx)));

    if(mid<d)   res=max(res,query2(tt,c,d,RR(idx)));

    return res;

}

 

int query(int a,int b,int c,int d,int idx)

{

    if(t[idx].left>=a&&t[idx].right<=b)

    {

        return query2(t[idx].tt,c,d,1);

    }

    int mid=t[idx].mid();

    int res=-1;

    if(mid>=a)  res=max(res,query(a,b,c,d,LL(idx)));

    if(mid<b)  res=max(res,query(a,b,c,d,RR(idx)));

   return res;

}

 

int main()

{

    int T;

    while(scanf("%d",&T)!=EOF)

    {

        if(T==0)  break;

        build(100,200,1);

        for(int i=1;i<=T;i++)

        {

            char str[5];

            scanf("%s",str);

            if(str[0]=='Q')

            {

                int a,b;

                double c,d;

                scanf("%d%d%lf%lf",&a,&b,&c,&d);

                if(a>b)    swap(a,b);

                if(c>d)    swap(c,d);

                int t=query(a,b,int(10*c),int(10*d),1);

                if(t<0)   printf("-1/n");

                else

                printf("%0.1lf/n",t*1.0/10);

            }

            else

            {

                int a;

                double b,c;

                scanf("%d%lf%lf",&a,&b,&c);

                update(a,int(b*10),int(c*10),1);

            }

        }

    }

    return 0;

}

二维线段树线段树二维空间上的扩展,用于高效处理二维区间的查询和更新操作。下面将详细阐述二维线段树的编写方法。 ### 1. 基本思路 二维线段树本质上是对二维空间进行递归划分,每个节点代表一个二维矩形区域。其构建过程可通过对行和列分别进行递归划分来实现。在更新和查询操作时,同样需要递归处理。 ### 2. 代码实现 ```python class SegmentTree2D: def __init__(self, matrix): self.matrix = matrix self.rows = len(matrix) self.cols = len(matrix[0]) if self.rows > 0 else 0 self.tree = [[0] * (4 * self.cols) for _ in range(4 * self.rows)] self.build(1, 0, self.rows - 1, 1, 0, self.cols - 1) def build(self, row_node, row_start, row_end, col_node, col_start, col_end): if row_start > row_end or col_start > col_end: return if row_start == row_end and col_start == col_end: self.tree[row_node][col_node] = self.matrix[row_start][col_start] return row_mid = (row_start + row_end) // 2 col_mid = (col_start + col_end) // 2 # 递归构建四个子树 self.build(row_node * 2, row_start, row_mid, col_node * 2, col_start, col_mid) self.build(row_node * 2, row_start, row_mid, col_node * 2 + 1, col_mid + 1, col_end) self.build(row_node * 2 + 1, row_mid + 1, row_end, col_node * 2, col_start, col_mid) self.build(row_node * 2 + 1, row_mid + 1, row_end, col_node * 2 + 1, col_mid + 1, col_end) # 合并子树信息 self.tree[row_node][col_node] = ( self.tree[row_node * 2][col_node * 2] + self.tree[row_node * 2][col_node * 2 + 1] + self.tree[row_node * 2 + 1][col_node * 2] + self.tree[row_node * 2 + 1][col_node * 2 + 1] ) def query(self, row_node, row_start, row_end, col_node, col_start, col_end, query_row_start, query_row_end, query_col_start, query_col_end): if row_start > query_row_end or row_end < query_row_start or col_start > query_col_end or col_end < query_col_start: return 0 if query_row_start <= row_start and row_end <= query_row_end and query_col_start <= col_start and col_end <= query_col_end: return self.tree[row_node][col_node] row_mid = (row_start + row_end) // 2 col_mid = (col_start + col_end) // 2 return ( self.query(row_node * 2, row_start, row_mid, col_node * 2, col_start, col_mid, query_row_start, query_row_end, query_col_start, query_col_end) + self.query(row_node * 2, row_start, row_mid, col_node * 2 + 1, col_mid + 1, col_end, query_row_start, query_row_end, query_col_start, query_col_end) + self.query(row_node * 2 + 1, row_mid + 1, row_end, col_node * 2, col_start, col_mid, query_row_start, query_row_end, query_col_start, query_col_end) + self.query(row_node * 2 + 1, row_mid + 1, row_end, col_node * 2 + 1, col_mid + 1, col_end, query_row_start, query_row_end, query_col_start, query_col_end) ) def update(self, row_node, row_start, row_end, col_node, col_start, col_end, update_row, update_col, new_val): if row_start > update_row or row_end < update_row or col_start > update_col or col_end < update_col: return if row_start == row_end and col_start == col_end: self.tree[row_node][col_node] = new_val return row_mid = (row_start + row_end) // 2 col_mid = (col_start + col_end) // 2 self.update(row_node * 2, row_start, row_mid, col_node * 2, col_start, col_mid, update_row, update_col, new_val) self.update(row_node * 2, row_start, row_mid, col_node * 2 + 1, col_mid + 1, col_end, update_row, update_col, new_val) self.update(row_node * 2 + 1, row_mid + 1, row_end, col_node * 2, col_start, col_mid, update_row, update_col, new_val) self.update(row_node * 2 + 1, row_mid + 1, row_end, col_node * 2 + 1, col_mid + 1, col_end, update_row, update_col, new_val) self.tree[row_node][col_node] = ( self.tree[row_node * 2][col_node * 2] + self.tree[row_node * 2][col_node * 2 + 1] + self.tree[row_node * 2 + 1][col_node * 2] + self.tree[row_node * 2 + 1][col_node * 2 + 1] ) # 示例用法 matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] seg_tree_2d = SegmentTree2D(matrix) # 查询 (0, 0) 到 (1, 1) 的区域和 result = seg_tree_2d.query(1, 0, len(matrix) - 1, 1, 0, len(matrix[0]) - 1, 0, 1, 0, 1) print("查询结果:", result) # 更新 (0, 0) 的值为 10 seg_tree_2d.update(1, 0, len(matrix) - 1, 1, 0, len(matrix[0]) - 1, 0, 0, 10) # 再次查询 (0, 0) 到 (1, 1) 的区域和 result = seg_tree_2d.query(1, 0, len(matrix) - 1, 1, 0, len(matrix[0]) - 1, 0, 1, 0, 1) print("更新后查询结果:", result) ``` ### 3. 代码解释 - **`__init__` 方法**:初始化二维线段树,接收一个二维矩阵作为输入,同时初始化树的节点数组,并调用 `build` 方法构建树。 - **`build` 方法**:递归构建二维线段树。对于每个节点,若为叶子节点,则直接赋值;否则,递归构建四个子树,并合并子树信息。 - **`query` 方法**:递归查询指定二维区域的和。若当前节点完全包含在查询区域内,则直接返回该节点的值;否则,递归查询四个子树并求和。 - **`update` 方法**:递归更新指定位置的值。若当前节点为叶子节点,则更新该节点的值;否则,递归更新四个子树,并重新合并子树信息。 ### 4. 复杂度分析 - **构建复杂度**:$O(m * n)$,其中 $m$ 和 $n$ 分别为矩阵的行数和列数。 - **查询复杂度**:$O(log m * log n)$。 - **更新复杂度**:$O(log m * log n)$。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值