LeetCode "Range Sum Query 2D - Mutable"

本文介绍了一种从二维区间树(2D Segment Tree)到四叉树(QuadTree)的数据结构转换方法,并提供了详细的C++实现代码。通过这种转换可以更高效地处理二维空间中的查询和更新操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2D Segment Tree -> Quad Tree. 

    
    class Node // 2D Segment Tree
    {
    public:
        Node(vector<vector<int>> &m, int ix0, int iy0, int ix1, int iy1)
            : sum(0), x0(ix0), x1(ix1), y0(iy0), y1(iy1),
              ul(nullptr), ur(nullptr), dl(nullptr), dr(nullptr)
        {
            if(ix0 > ix1 || iy0 > iy1) return;
            
            if(ix0 == ix1 && iy0 == iy1)
            {
                sum = m[iy0][ix0];
                return;
            }
            
            int xmid = getMidX();
            int ymid = getMidY();
            
            ul = new Node(m, ix0, iy0, xmid, ymid);
            sum += ul->sum;
            if(ix1 > xmid)
            {
                ur = new Node(m, xmid + 1, iy0, ix1, ymid);
                sum += ur->sum;
            }
            if(iy1 > ymid)
            {
                dl = new Node(m, ix0, ymid + 1, xmid, iy1);
                sum += dl->sum;
            }
            if(iy1 > ymid && ix1 > xmid)
            {
                dr = new Node(m, xmid + 1, ymid + 1, ix1, iy1);
                sum += dr->sum;
            }
        }
        
        long long update(int rx, int ry, long long val)
        {
            if(rx == x0 && ry == y0 && x0 == x1 && y0 == y1)
            {
                long long d = val - sum;
                sum = val;
                return d;
            }
            
            int xmid = getMidX();
            int ymid = getMidY();
            
            long long d = 0;
            if(rx <= xmid && ry <= ymid)
            {
                d = ul->update(rx, ry, val);
            }
            else if(rx > xmid && ry <= ymid)
            {
                d = ur->update(rx, ry, val);
            }
            else if(rx <= xmid && ry > ymid)
            {
                d = dl->update(rx, ry, val);
            }
            else if(rx > xmid && ry > ymid)
            {
                d = dr->update(rx, ry, val);
            }
            sum += d;
            return d;
        }
        
        long long get(int rx0, int ry0, int rx1, int ry1)
        {
            if(rx0 == x0 && rx1 == x1 && ry0 == y0 && ry1 == y1)
            {
                return sum;
            }
            //
            int xmid = getMidX();
            int ymid = getMidY();
            
            long long d = 0;        
            if(rx0 <= xmid && ry0 <= ymid)
            {
                d += ul->get(rx0, ry0, min(xmid, rx1), min(ymid, ry1));
            }        
            if(rx1 > xmid && ry0 <= ymid)
            {
                d += ur->get(max(rx0, xmid + 1), ry0, rx1, min(ymid, ry1));
            }
            if(rx0 <= xmid && ry1 > ymid)
            {
                d += dl->get(rx0, max(ymid + 1, ry0), min(rx1, xmid), ry1);
            }
            if(rx1 > xmid && ry1 > ymid)
            {
                d += dr->get(max(rx0, xmid + 1), max(ry0, ymid + 1), rx1, ry1);
            }
            
            return d;
        }
    private:    
        int getMidX(){ return x0 + (x1 - x0) / 2; }
        int getMidY(){ return y0 + (y1 - y0) / 2; }
    private:    
        //    mem vars
        long long sum;
        int x0, x1;
        int y0, y1;
        
        Node *ul;
        Node *ur;
        Node *dl;
        Node *dr;
    };
    
    class NumMatrix 
    {
        Node *pSeg;
    public:
        NumMatrix(vector<vector<int>> &matrix) 
        {
            int h = matrix.size();
            if(!h) return;
            int w = matrix[0].size();
            
            pSeg = new Node(matrix, 0, 0, w - 1, h - 1);
        }
    
        void update(int row, int col, int val) 
        {
            if(pSeg)
                pSeg->update(col, row, val);
        }
    
        int sumRegion(int row1, int col1, int row2, int col2) 
        {
            if(pSeg)
                return pSeg->get(col1, row1, col2, row2);
            return 0;
        }
    };
View Code

 

转载于:https://www.cnblogs.com/tonix/p/4987341.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值