• UVA11992


    UVA11992 - Fast Matrix Operations(线段树区间改动)

    题目链接

    题目大意:给你个r*c的矩阵,初始化为0。
    然后给你三种操作:
    1 x1, y1, x2, y2, v 把由x1,y1, x2, y2构成的子矩阵里的每一个元素都加上v。
    2 x1, y1, x2, y2, v 把这个子矩阵的每一个元素都改动为v。
    3 x1, y1, x2, y2 查询这个子矩阵的元素之和,和这些元素的最大值和最小值。

    解题思路:由于矩阵的行最多20行,所以能够将这个矩阵的元素构建一棵线段树,每一个节点都有三个附加信息:sum,Max_num, Min_num.然后改动查询的时候就每行每行的来做。注意:每次set的时候都要将这个节点的add清理掉。由于add已经是不须要的了。

    然后每次的pushdown都要先处理set再处理add。pushdown处理的是这个节点的子节点。然后通过pushup就能够更新这个节点的附加信息。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    #define lson(x) ((x)<<1)
    #define rson(x) (((x)<<1) + 1)
    
    const int N = 1e6 + 5;
    const int INF = 0x3f3f3f3f;
    
    struct Item {
    
        int sum, Max_num, Min_num;
    
        Item (int sum = 0, int Max_num = -INF, int Min_num = INF) {
            this->set(sum, Max_num, Min_num);
        }
    
        void set (int sum, int Max_num, int Min_num) {
            this->sum = sum;
            this->Max_num = Max_num;
            this->Min_num  = Min_num;
        }
    };
    
    struct Node {
    
        Item v;
        int l, r;
        int addv, setv;
    
        void set (int l, int r, int addv = 0, int setv = -1) {
            this->l = l;
            this->r = r;
            this->addv = addv;
            this->setv = setv;    
        }
    
    }node[4 * N];
    
    Item get_item (Item a, Item b) {
    
        return Item(a.sum + b.sum, max(a.Max_num, b.Max_num), min(a.Min_num, b.Min_num));
    }
    
    void Node_add(int u, int addv) {
    
        node[u].addv += addv;
        node[u].v.sum += addv * (node[u].r - node[u].l + 1);
        node[u].v.Max_num += addv;
        node[u].v.Min_num += addv;
    }
    
    void Node_set(int u, int setv) {
    
        node[u].setv = setv;
        node[u].addv = 0;
        node[u].v.sum = setv * (node[u].r - node[u].l + 1);
        node[u].v.Max_num = node[u].v.Min_num = setv;
    }
    
    void pushup (int u) {
    
        node[u].set(node[lson(u)].l, node[rson(u)].r);
        node[u].v = get_item(node[lson(u)].v, node[rson(u)].v);
    }
    
    void pushdown(int u) {
    
        if (node[u].setv >= 0) {
            Node_set(lson(u), node[u].setv);
            Node_set(rson(u), node[u].setv);
            node[u].setv = -1;
        }
    
        if (node[u].addv) {
            Node_add(lson(u), node[u].addv);
            Node_add(rson(u), node[u].addv);
            node[u].addv = 0;    
        }
    }
    
    void Build (int u, int l, int r) {
    
        if (l == r) { 
            node[u].set(l, r);
            node[u].v.set(0, 0, 0);
    
        } else {
    
            int m = (l + r) / 2;
            Build(lson(u), l, m);
            Build(rson(u), m + 1, r);
            pushup(u);
        }
    }
    
    void Add (int u, int l, int r, int addv) {
    
        if (node[u].l >= l && node[u].r <= r)
            Node_add(u, addv);
        else {
    
            pushdown(u);
            int m = (node[u].l + node[u].r) / 2;
            if (l <= m)
                Add (lson(u), l, r, addv);
            if (r > m)
                Add (rson(u), l, r, addv);
            pushup(u);
        }
    }
    
    void Set (int u, int l, int r, int setv) {
    
        if (node[u].l >= l && node[u].r <= r)
            Node_set(u, setv);
        else {
    
            pushdown(u);
            int m = (node[u].l + node[u].r) / 2;
            if (l <= m)
                Set (lson(u), l, r, setv);
            if (r > m)
                Set (rson(u), l, r, setv);
            pushup(u);
        }
    }
    
    Item Query (int u, int l, int r) {
    
        if (node[u].l >= l && node[u].r <= r) 
            return node[u].v;
        else {
    
            Item ans;
    
            pushdown(u);
            int m = (node[u].l + node[u].r) / 2;
            if (l <= m)
                ans = get_item (ans, Query(lson(u), l, r));
            if (r > m)
                ans = get_item (ans, Query(rson(u), l, r));    
            pushup(u);
    
            return ans;
        }
    }
    
    int main () {
    
        int r, c, m;
        int type;
        int x1, y1, x2, y2, v;
    
        while (scanf ("%d%d%d", &r, &c, &m) != EOF) {
    
            Build(1, 1, r * c);
    
            while (m--) {
    
                scanf ("%d", &type);
    
                if (type == 1) {
    
                    scanf ("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v);
    
                    for (int i = x1 - 1; i < x2; i++)
                        Add(1, i * c + y1, i * c + y2, v);
                } else if (type == 2) {
    
                    scanf ("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v);
                    for (int i = x1 - 1; i < x2; i++)
                        Set(1, i * c + y1, i * c + y2, v);
                } else {
    
                    scanf ("%d%d%d%d", &x1, &y1, &x2, &y2);
    
                    Item ans;
                    for (int i = x1 - 1; i < x2; i++)
                        ans = get_item(ans, Query(1, i * c + y1, i * c + y2));
                    printf ("%d %d %d
    ", ans.sum, ans.Min_num, ans.Max_num);
                }
            }
        }
        return 0;
    }

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    做报表,写Sql语句的一点收获
    ORACLE PL/SQ入门
    用Visual C#实现P2P应用程序
    css资源网站收集推荐
    Ubuntu 蓝牙全攻略
    Asp.Net细节性问题技巧精萃
    Asp.net Request获取服务器变量的方法
    如何将flash插入到Excel文件中
    XP远程桌面连接强制登录
    flash研究(三)——Falsh与JavaScript交互
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4854657.html
Copyright © 2020-2023  润新知