uva11992-Fast Matrix Operations(区间增值、改值)

题意:

r行c列的全0矩阵   有三种操作 1 x1 y1 x2 y2 v子矩阵(x1,y1,x2,y2)所有元素增加v

              2 x1 y1 x2 y2 v子矩阵(x1,y1,x2,y2)所有元素设为v

              3 x1 y1 x2 y2 查询子矩阵元素的和、最小值、最大值

分析:线段树的区间更新 、把矩阵化为一维。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)|1)
#define INF 0x3f3f3f3f
const int N = 1000005;
int r, c, m;
struct Node {
    int l, r;
    int sum, Max, Min, sumv, setv;
} node[4 * N];
void pushup(int x) {
    node[x].sum = node[lson(x)].sum + node[rson(x)].sum;
    node[x].Max = max(node[lson(x)].Max, node[rson(x)].Max);
    node[x].Min = min(node[lson(x)].Min, node[rson(x)].Min);
}

void pushdown(int x) {
    if (node[x].setv) {
    node[lson(x)].sumv = node[rson(x)].sumv = 0;
    node[lson(x)].setv = node[rson(x)].setv = node[x].setv;
    node[lson(x)].sum = (node[lson(x)].r - node[lson(x)].l + 1) * node[x].setv;
    node[rson(x)].sum = (node[rson(x)].r - node[rson(x)].l + 1) * node[x].setv;
    node[lson(x)].Max = node[lson(x)].Min = node[x].setv;
    node[rson(x)].Max = node[rson(x)].Min = node[x].setv;
    node[x].setv = 0;
    }
    if (node[x].sumv) {
    node[lson(x)].sumv += node[x].sumv;
    node[rson(x)].sumv += node[x].sumv;
    node[lson(x)].sum += (node[lson(x)].r - node[lson(x)].l + 1) * node[x].sumv;
    node[rson(x)].sum += (node[rson(x)].r - node[rson(x)].l + 1) * node[x].sumv;
    node[lson(x)].Max += node[x].sumv;
    node[lson(x)].Min += node[x].sumv;
    node[rson(x)].Max += node[x].sumv;
    node[rson(x)].Min += node[x].sumv;
    node[x].sumv = 0;
    }
}

void build(int l, int r, int x) {
    node[x].l = l; node[x].r = r;
    if (l == r) {
    node[x].sum = node[x].Max = node[x].Min = node[x].sumv = node[x].setv = 0;
    return;
    }
    int mid = (l + r) / 2;
    build(l, mid, lson(x));
    build(mid + 1, r, rson(x));
    pushup(x);
}

void update_add(int l, int r, int v, int x) {
    if (node[x].l >= l && node[x].r <= r) {
    node[x].sumv += v;
    node[x].sum += (node[x].r - node[x].l + 1) * v;
    node[x].Max += v;
    node[x].Min += v;
    return;
    }
    pushdown(x);
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) update_add(l, r, v, lson(x));
    if (r > mid) update_add(l, r, v, rson(x));
    pushup(x);
}

void update_set(int l, int r, int v, int x) {
    if (node[x].l >= l && node[x].r <= r) {
    node[x].setv = v;
    node[x].sum = (node[x].r - node[x].l + 1) * v;
    node[x].Max = node[x].Min = v;
    node[x].sumv = 0;
    return;
    }
    pushdown(x);
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) update_set(l, r, v, lson(x));
    if (r > mid) update_set(l, r, v, rson(x));
    pushup(x);
}

Node query(int l, int r, int x) {
    Node ans; ans.sum = 0; ans.Max = 0; ans.Min = INF;
    if (node[x].l >= l && node[x].r <= r) {
    ans.sum = node[x].sum;
    ans.Max = node[x].Max;
    ans.Min = node[x].Min;
    return ans;
    }
    pushdown(x);
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) {
    Node tmp = query(l, r, lson(x));
    ans.sum += tmp.sum;
    ans.Max = max(ans.Max, tmp.Max);
    ans.Min = min(ans.Min, tmp.Min);
    }
    if (r > mid) {
    Node tmp = query(l, r, rson(x));
    ans.sum += tmp.sum;
    ans.Max = max(ans.Max, tmp.Max);
    ans.Min = min(ans.Min, tmp.Min);
    }
    return ans;
}

int main() {
    while (~scanf("%d%d%d", &r, &c, &m)) {
    build(1, r * c, 1);
    int q, x1, y1, x2, y2, v;
    while (m--) {
        scanf("%d", &q);
        if (q == 3) {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        int sum = 0, Max = 0, Min = INF;
        for (int i = x1; i <= x2; i++) {
            Node ans = query((i-1)* c + y1, (i-1) * c + y2, 1);
            sum += ans.sum;
            Max = max(Max, ans.Max);
            Min = min(Min, ans.Min);
        }
        printf("%d %d %d\n", sum, Min, Max);
        }
        else {
        scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v);
        for (int i = x1; i <= x2; i++) {
            if (q == 1) update_add((i-1) * c + y1, (i-1) * c + y2, v, 1);
            else update_set((i-1) * c + y1, (i-1) * c + y2, v, 1);
        }
        }
    }
    }
    return 0;
}
时间: 2024-10-12 23:58:32

uva11992-Fast Matrix Operations(区间增值、改值)的相关文章

UVA11992 - Fast Matrix Operations ( 线段树 + 区间修改 + 好题 )

UVA11992 - Fast Matrix Operations ( 线段树 + 区间修改 + 好题 ) 这是大白书上的例题,一直放着没有去A掉,这是一道线段树区间修改的好题. 线段树中需要维护三个域 ,max, min, sum,也就是区间最大值,最小值,区间和 题目大意: r 行 c 列 的全0矩阵,支持三个操作 1 x1 y1 x2 y2 v 子矩阵(x1,y1,x2,y2)的所有元素增加v 2 x1 y1 x2 y2 v 子矩阵(x1,y1,x2,y2)的所有元素设为v 3 x1 y1

UVA11992 - Fast Matrix Operations(段树部分的变化)

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行,所以能够将这个矩阵的元素构建一

[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)

题目链接:https://vjudge.net/problem/UVA-11992 题意:n*m的矩阵,每次对一个子矩阵操作,有三种操作:加x,设置为x,查询.查询返回子矩阵和.最小值.最大值 n很小(<=20),所以可以开20棵线段树,每次操作按行更新. 特别小心put和add两个延迟标记,坑老惨了. put初始化-1最简单的坑,略过. build的时候要每一个节点都要clear,不能只clear叶子.因为会有直接差没操作的子矩阵(因为初始化都是0). 数组开大... add的话,什么都不用管

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.然后修改查询

UVA11992:Fast Matrix Operations(线段树)

题意: 有一个初始状态全为0的矩阵,一共有三个操作 1 x1 y1 x2 y2 v:子矩阵(x1,y1,x2,y2)所有元素增加v 2 x1 y1 x2 y2 v:子矩阵(x1,y1,x2,y2)所有元素设为v 3 x1 y1 x2 y2 v:查询子矩阵(x1,y1,x2,y2)的元素和,最大值和最小值 思路: 因为总元素葛素不超过10^6,而且更新是对于连续的行进行更新,所以我们可以把矩阵转化为一个一元组,通过下一行拼接在上一行的末尾,那么在更新与查询的时候只要对相应的区间进行操作即可 #in

uva11992 Fast Matrix Operations

题意:r*c的矩阵上,初始全部为0,有3中操作,子矩阵全部增加v,子矩阵值修改为v,查询子矩阵的最大值,最小值,和 分析:因为有setv和addv两种操作,那么需要开两个数组记录这个值,每次需要用到一个节点的儿子,那么就把该节点的setv,addv信息推过去,并且setv的优先级要高于addv,不过这样的后果就是,慢 不过这样写思维难度和编程难度降低了,一般并不会发生线段树不够快的情况 1 #include<iostream> 2 #include<cstring> 3 #incl

UVA 11992 - Fast Matrix Operations

Fast Matrix Operations There is a matrix containing at most 106 elements divided into r rows and c columns. Each element has a location (x,y) where 1<=x<=r,1<=y<=c. Initially, all the elements are zero. You need to handle four kinds of operati

Fast Matrix Operations(UVA)11992

UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val: 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val: 3 x1 y1 x2 y2 val 表示输

Fast Matrix Operations

uva11992:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143 题意:给你n*m的矩阵初始化的时候矩阵里面的元素全部是0,对于这个矩阵有3中操作. 1 x1 y1 x2 y2 v   把(x1 y1 x2 y2)子矩阵 里面的元素全部加上v 2 x1 y1 x2 y2 v   把(x1 y1 x2 y2)子矩阵 里面的元素全部置成

UVa 11992 Fast Matrix Operations (线段树)

Fast Matrix Operations Description There is a matrix containing at most 106 elements divided into r rows and c columns. Each element has a location (x, y) where 1 ≤ x ≤ r, 1 ≤ y ≤ c. Initially, all the elements are zero. You need to handle four kinds