Uva 11992 Fast Matrix Operations 【线段树】【双标记pushdown】

#include<bits/stdc++.h>
using namespace std;
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
const int MAX = 1e5 + 7;
const int INF = 0x3f3f3f3f;
struct node{
    int sum, mn, mx, add, sett;
} a[25][MAX << 2];
void pushdown(int rt, int l, int r, int num){
    int mid = (l + r) >> 1;
    if(a[num][rt].sett >= 0){
        a[num][rt << 1].sett = a[num][rt << 1 | 1].sett = a[num][rt].sett;
        a[num][rt << 1].mn = a[num][rt << 1 | 1].mn = a[num][rt].sett;
        a[num][rt << 1].mx = a[num][rt << 1 | 1].mx = a[num][rt].sett;
        a[num][rt << 1].add = a[num][rt << 1 | 1].add = 0;
        a[num][rt << 1].sum = (mid - l + 1) * a[num][rt].sett;
        a[num][rt << 1 | 1].sum = (r - mid) * a[num][rt].sett;
        a[num][rt].sett = -1;
    }
    if(a[num][rt].add > 0){
        a[num][rt << 1].add += a[num][rt].add;
        a[num][rt << 1 | 1].add += a[num][rt].add;
        a[num][rt << 1 | 1].mn += a[num][rt].add;
        a[num][rt << 1 | 1].mx += a[num][rt].add;
        a[num][rt << 1].mx += a[num][rt].add;
        a[num][rt << 1].mn += a[num][rt].add;
        a[num][rt << 1].sum += (mid - l + 1) * a[num][rt].add;
        a[num][rt << 1 | 1].sum += (r - mid) * a[num][rt].add;
        a[num][rt].add = 0;
    }
}
void pushup(int rt, int num){
    a[num][rt].sum = a[num][rt << 1].sum +  a[num][rt << 1 | 1].sum;
    a[num][rt].mx = max(a[num][rt << 1].mx, a[num][rt << 1 | 1].mx);
    a[num][rt].mn = min(a[num][rt << 1].mn, a[num][rt << 1 | 1].mn);
}
void build(int rt, int l, int r, int num){
    a[num][rt].sett = -1, a[num][rt].sum = a[num][rt].mx = a[num][rt].mn = a[num][rt].add = 0;
    if(l == r) return;
    int mid = (l + r) >> 1;
    build(lson, num), build(rson, num);
}
void update_fuck(int rt, int l, int r, int x, int y, int v, int num){
    if(x <= l && r <= y){
        a[num][rt].sum += (r - l + 1) * v;
        a[num][rt].mn += v;
        a[num][rt].mx += v;
        a[num][rt].add += v;
        return;
    }
    pushdown(rt, l, r, num);
    int mid = (l + r) >> 1;
    if(x <= mid) update_fuck(lson, x, y, v, num);
    if(mid < y) update_fuck(rson, x, y, v, num);
    pushup(rt, num);
}
void update_shit(int rt, int l, int r, int x, int y, int v, int num){
    if(x <= l && r <= y){
        a[num][rt].sum = (r - l + 1) * v;
        a[num][rt].mn = v;
        a[num][rt].mx = v;
        a[num][rt].add = 0;
        a[num][rt].sett = v;
        return;
    }
    pushdown(rt, l, r, num);
    int mid = (l + r) >> 1;
    if(x <= mid) update_shit(lson, x, y, v, num);
    if(mid < y) update_shit(rson, x, y, v, num);
    pushup(rt, num);
}
int querySum(int rt, int l, int r, int x, int y, int num){
    if(x <= l && r <= y) return a[num][rt].sum;
    int mid = (l + r) >> 1;
    pushdown(rt, l, r, num);
    int ans = 0;
    if(x <= mid) ans += querySum(lson, x, y, num);
    if(mid < y) ans += querySum(rson, x, y, num);
    return ans;
}
int queryMin(int rt, int l, int r, int x, int y, int num){
    if(x <= l && r <= y) return a[num][rt].mn;
    pushdown(rt, l, r, num);
    int ans = INF;
    int mid = (l + r) >> 1;
    if(x <= mid) ans = min(ans, queryMin(lson, x, y, num));
    if(mid < y) ans = min(ans, queryMin(rson, x, y, num));
    return ans;
}
int queryMax(int rt, int l, int r, int x, int y, int num){
    if(x <= l && r <= y) return a[num][rt].mx;
    pushdown(rt, l, r, num);
    int ans = -INF;
    int mid = (l + r) >> 1;
    if(x <= mid) ans = max(ans, queryMax(lson, x, y, num));
    if(mid < y) ans = max(ans, queryMax(rson, x, y, num));
    return ans;
}
int main(){
    int n, m, q;
    while(scanf("%d%d%d", &n, &m, &q) != EOF){
        for(int i = 1; i <= n; i++) build(1, 1, m, i);
        for(int i = 0, x1, y1, x2, y2, hhd, op; i < q; i++){
            scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
            if(op != 3) scanf("%d", &hhd);
            if(op == 1) for(int i = x1; i <= x2; i++) update_fuck(1, 1, m, y1, y2, hhd, i);
            else if(op == 2) for(int i = x1; i <= x2; i++) update_shit(1, 1, m, y1, y2, hhd, i);
            else{
                int sum = 0, mx = -INF, mn = INF;
                for(int i = x1; i <= x2; i++){
                    sum += querySum(1, 1, m, y1, y2, i);
                    mn = min(mn, queryMin(1, 1, m, y1, y2, i));
                    mx = max(mx, queryMax(1, 1, m, y1, y2, i));
                }
                printf("%d %d %d\n", sum, mn, mx);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Head_Hard/article/details/82155515