UVA - 11992 Fast Matrix Operations——线段树

先set后add

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 5e4 + 10;
const int INF = 0x3f3f3f3f;
struct Node {
    int sum, minv, maxv;
    int lazy_set, lazy_add;
}node[25][maxn<<2];
void pushup(int idx, int root) {
    node[idx][root].sum = node[idx][root<<1].sum + node[idx][root<<1|1].sum;
    node[idx][root].minv = min(node[idx][root<<1].minv, node[idx][root<<1|1].minv);
    node[idx][root].maxv = max(node[idx][root<<1].maxv, node[idx][root<<1|1].maxv);
}
void pushdown(int idx, int root, int lenl, int lenr) {
    if (node[idx][root].lazy_set >= 0) {
        node[idx][root<<1].lazy_set = node[idx][root].lazy_set;
        node[idx][root<<1|1].lazy_set = node[idx][root].lazy_set;
        node[idx][root<<1].sum = lenl * node[idx][root].lazy_set;
        node[idx][root<<1|1].sum = lenr * node[idx][root].lazy_set;
        node[idx][root<<1].minv = node[idx][root].lazy_set;
        node[idx][root<<1|1].minv = node[idx][root].lazy_set;
        node[idx][root<<1].maxv = node[idx][root].lazy_set;
        node[idx][root<<1|1].maxv = node[idx][root].lazy_set;
        node[idx][root<<1].lazy_add = 0;
        node[idx][root<<1|1].lazy_add = 0;
        node[idx][root].lazy_set = -1;
    }
    if (node[idx][root].lazy_add > 0) {
        node[idx][root<<1].lazy_add += node[idx][root].lazy_add;
        node[idx][root<<1|1].lazy_add += node[idx][root].lazy_add;
        node[idx][root<<1].sum += lenl * node[idx][root].lazy_add;
        node[idx][root<<1|1].sum += lenr * node[idx][root].lazy_add;
        node[idx][root<<1].minv += node[idx][root].lazy_add;
        node[idx][root<<1|1].minv += node[idx][root].lazy_add;
        node[idx][root<<1].maxv += node[idx][root].lazy_add;
        node[idx][root<<1|1].maxv += node[idx][root].lazy_add;
        node[idx][root].lazy_add = 0;
    }
}
void build(int l, int r, int idx, int root) {
    node[idx][root].sum = 0;
    node[idx][root].minv = 0;
    node[idx][root].maxv = 0;
    node[idx][root].lazy_set = -1;
    node[idx][root].lazy_add = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(l, mid, idx, root<<1);
    build(mid+1, r, idx, root<<1|1);
    pushup(idx, root);
}
void update(int l, int r, int idx, int root, int ul, int ur, int flag, int v) {
    if (ul <= l && r <= ur) {
        if (flag == 1) {
            node[idx][root].lazy_add += v;
            node[idx][root].sum += (r - l + 1) * v;
            node[idx][root].minv += v;
            node[idx][root].maxv += v;
        }
        else {
            node[idx][root].lazy_set = v;
            node[idx][root].lazy_add = 0;
            node[idx][root].sum = (r - l + 1) * v;
            node[idx][root].minv = v;
            node[idx][root].maxv = v;
        }
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(idx, root, mid - l + 1, r - mid);
    if (ul <= mid) update(l, mid, idx, root<<1, ul, ur, flag, v);
    if (mid < ur) update(mid + 1, r, idx, root<<1|1, ul, ur, flag, v);
    pushup(idx, root);
}
int query1(int l, int r, int idx, int root, int ql, int qr) {
    if (ql <= l && r <= qr) return node[idx][root].sum;
    int mid = (l + r) >> 1;
    pushdown(idx, root, mid - l + 1, r - mid);
    int ans = 0;
    if (ql <= mid) ans += query1(l, mid, idx, root<<1, ql, qr);
    if (mid < qr) ans += query1(mid+1, r, idx, root<<1|1, ql, qr);
    return ans;
}
int query2(int l, int r, int idx, int root, int ql, int qr) {
    if (ql <= l && r <= qr) return node[idx][root].minv;
    int mid = (l + r) >> 1;
    pushdown(idx, root, mid - l + 1, r - mid);
    int ans = INF;
    if (ql <= mid) ans = min(ans, query2(l, mid, idx, root<<1, ql, qr));
    if (mid < qr) ans = min(ans, query2(mid+1, r, idx, root<<1|1, ql, qr));
    return ans;
}
int query3(int l, int r, int idx, int root, int ql, int qr) {
    if (ql <= l && r <= qr) return node[idx][root].maxv;
    int mid = (l + r) >> 1;
    pushdown(idx, root, mid - l + 1, r - mid);
    int ans = 0;
    if (ql <= mid) ans = max(ans, query3(l, mid, idx, root<<1, ql, qr));
    if (mid < qr) ans = max(ans, query3(mid + 1, r, idx, root<<1|1, ql, qr));
    return ans;
}
int n, m, q;
int main() {
    while (~scanf("%d%d%d", &n, &m, &q)) {
        for (int i = 1; i <= n; i++) build(1, m, i, 1);
        int flag, x1, y1, x2, y2, v;
        while (q--) {
            scanf("%d", &flag);
            if (flag == 1 || flag == 2) {
                scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v);
                for (int i = x1; i <= x2; i++) update(1, m, i, 1, y1, y2, flag, v);
            }
            else {
                scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
                int ans1 = 0, ans2 = INF, ans3 = 0;
                for (int i = x1; i <= x2; i++) {
                    ans1 += query1(1, m, i, 1, y1, y2);
                    ans2 = min(ans2, query2(1, m, i, 1, y1, y2));
                    ans3 = max(ans3, query3(1, m, i, 1, y1, y2));
                }
                printf("%d %d %d\n", ans1, ans2, ans3);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/80057359