zoukankan      html  css  js  c++  java
  • bzoj1513

    二维线段树

    听说二维线段树不能下传标记?

    就是裸的二维线段树,由于每次高度只能增加,所以我们就可以标记永久化

    每个线段树里有两个数组,mx和mark,每次修改路径上所有mx都要修改,mark是区间的精确覆盖修改

    每次查询把路径上所有mark取max,然后和精确覆盖区间mx取max

    为什么这样做呢?我们能不能只用一个数组?当然不行,如果我们只用mark,那么假设我们更新区间[1,4],然后查询区间[1,5],那么答案明显不对,如果我们只用mx,那么我们更新[1,1],查询[2,2],那么我们的答案被[1,1]更新了,也是不对。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 3010;
    int n, m, t;
    struct Segment_Tree_X {
        int mx[N], mark[N];
        void update(int l, int r, int x, int a, int b, int tmp)
        {
            if(l > b || r < a) return;
            mx[x] = max(mx[x], tmp);
            if(l >= a && r <= b) 
            {
                mark[x] = max(mark[x], tmp);
                return;
            }
            int mid = (l + r) >> 1;
            update(l, mid, x << 1, a, b, tmp);
            update(mid + 1, r, x << 1 | 1, a, b, tmp);
        }
        int query(int l, int r, int x, int a, int b)
        {
            if(l > b || r < a) return 0;
            if(l >= a && r <= b) return mx[x];
            int mid = (l + r) >> 1;
            return max(mark[x], max(query(l, mid, x << 1, a, b), query(mid + 1, r, x << 1 | 1, a, b)));
        }
    };
    struct Segment_Tree_Y {
        Segment_Tree_X mx[N], mark[N];
        void update(int l, int r, int x, int a, int b, int y_l, int y_r, int tmp)
        {
            if(l > b || r < a) return;
            mx[x].update(1, m, 1, y_l, y_r, tmp);
            if(l >= a && r <= b)
            {
                mark[x].update(1, m, 1, y_l, y_r, tmp);
                return;
            }
            int mid = (l + r) >> 1;
            update(l, mid, x << 1, a, b, y_l, y_r, tmp);
            update(mid + 1, r, x << 1 | 1, a, b, y_l, y_r, tmp);
        }
        int query(int l, int r, int x, int a, int b, int y_l, int y_r)
        {
            if(l > b || r < a) return 0;
            if(l >= a && r <= b) return mx[x].query(1, m, 1, y_l, y_r);
            int mid = (l + r) >> 1;
            return max(mark[x].query(1, m, 1, y_l, y_r), max(query(l, mid, x << 1, a, b, y_l, y_r), query(mid + 1, r, x << 1 | 1, a, b, y_l, y_r)));
        }
    } T;
    int main()
    {
        scanf("%d%d%d", &n, &m, &t);
        while(t --)
        {
            int d, s, w, x, y, tmp;
            scanf("%d%d%d%d%d", &d, &s, &w, &x, &y);
            ++ x;
            ++ y;
            tmp = T.query(1, n, 1, x, x + d - 1, y, y + s - 1);
            T.update(1, n, 1, x, x + d - 1, y, y + s - 1, w + tmp);
        }
        printf("%d
    ", T.query(1, n, 1, 1, n, 1, m));
        return 0;
    }
    View Code
  • 相关阅读:
    SQL 强化练习 (七)
    SQL 强化练习 (六)
    SQL 强化练习 (五)
    SQL 强化练习 (四)
    典型相关分析 CCA
    SQL 强化练习(三)
    双向 和 多重 RNN
    SQL 强化练习 (二)
    SQL 强化练习 (一)
    SQL 查询强化
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7470639.html
Copyright © 2011-2022 走看看