11992 - Fast Matrix Operations

要wa死了,书上的代码没太看懂,就按照自己的想法写的,其中掺杂了书上的一些代码居然不对,唉……

#include <iostream>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>

#define INF 0x7fffffff
#define N 10010
#define M 1000010
#define LL long long
#define mod 95041567

using namespace std;

struct node{
    int MAX, MIN, ADD, SET, SUM;
};

node p;
node G[22][M << 2];
int cnt;

void pushdown(int i, int rt, int L, int R){
    int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L;
    if(G[i][rt].SET != INF){
        G[i][lc].SET = G[i][rc].SET = G[i][rt].SET;
        G[i][rt].SUM = (R - L + 1) * G[i][rt].SET;
        G[i][rc].SUM = (R - mid) * G[i][rt].SET;
        G[i][lc].SUM = (mid + 1 - L) * G[i][rt].SET;
        G[i][rt].MIN = G[i][rc].MIN = G[i][lc].MIN = G[i][rt].SET;
        G[i][rt].MAX = G[i][rc].MAX = G[i][lc].MAX = G[i][rt].SET;
        G[i][rt].SET = INF;
        G[i][rc].ADD = G[i][lc].ADD = 0;
    }
    if(G[i][rt].ADD){
        G[i][lc].MIN += G[i][rt].ADD;
        G[i][lc].MAX += G[i][rt].ADD;
        G[i][lc].ADD += G[i][rt].ADD;
        G[i][lc].SUM += G[i][rt].ADD * (mid + 1 - L);

        G[i][rc].MIN += G[i][rt].ADD;
        G[i][rc].MAX += G[i][rt].ADD;
        G[i][rc].ADD += G[i][rt].ADD;
        G[i][rc].SUM += G[i][rt].ADD * (R - mid);

        G[i][rt].ADD = 0;
    }
}

void maintain(int i, int rt, int L, int R){
    if(R <= L) return;
    int lc = rt << 1, rc = (rt << 1) | 1;
    G[i][rt].SUM = G[i][lc].SUM + G[i][rc].SUM;
    G[i][rt].MIN = min(G[i][lc].MIN, G[i][rc].MIN);
    G[i][rt].MAX = max(G[i][lc].MAX, G[i][rc].MAX);
    G[i][rt].SUM += G[i][rt].ADD * (R - L + 1);
    G[i][rt].MIN += G[i][rt].ADD;
    G[i][rt].MAX += G[i][rt].ADD;
}

void update(int i,int f, int rt, int L, int R, int y1, int y2, int v){
    if(y1 == L && y2 == R){
        if(f){
            G[i][rt].MAX = G[i][rt].MIN = G[i][rt].SET = v;
            G[i][rt].SUM = v * (R - L + 1);
            G[i][rt].ADD = 0;
        }
        else{
            G[i][rt].ADD += v;
            G[i][rt].MIN += v;
            G[i][rt].MAX += v;
            G[i][rt].SUM += (R - L + 1) * v;
        }
        return;
    }
    pushdown(i, rt, L, R);
    int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L;
    if(y2 <= mid) update(i, f, lc, L, mid, y1, y2, v);
    else if(y1 > mid) update(i, f, rc, mid + 1, R, y1, y2, v);
    else{
        update(i, f, lc, L, mid, y1, mid, v);
        update(i, f, rc, mid + 1, R, mid + 1, y2, v);
    }
    maintain(i, rt, L, R);
}

void query(int i, int rt, int L, int R, int y1, int y2){
    if(L == y1 && R == y2){
        p.MAX = max(p.MAX, G[i][rt].MAX);
        p.MIN = min(p.MIN, G[i][rt].MIN);
        p.SUM += G[i][rt].SUM;
        return;
    }
    pushdown(i, rt, L, R);
    int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L;
    if(y1 > mid) query(i, rc, mid + 1, R, y1, y2);
    else if(y2 <= mid) query(i, lc, L, mid, y1, y2);
    else{
        query(i, rc, mid + 1, R, mid + 1, y2);
        query(i, lc, L, mid, y1 ,mid);
    }
    maintain(i, rt, L, R);
}

int main()
{
    int r, c, q;
    //freopen("in.txt","r",stdin);
    while(scanf("%d %d %d", &r, &c, &q) != EOF){
        for(int i = 0; i < r; ++i)
            for(int j = c << 2; j >= 0; -- j)
                G[i][j].MAX = G[i][j].MIN = G[i][j].ADD = G[i][j].SUM = 0, G[i][j].SET = INF;
        int f, x1, y1, x2, y2, v;
        for(int i = 0; i < q; ++ i){
            cnt = i;
            scanf("%d %d %d %d %d", &f, &x1, &y1, &x2, &y2);
            -- f, -- x1, -- x2, -- y1, -- y2;
            if(f <= 1){
                scanf("%d", &v);
                for(int j = x1; j <= x2; ++ j) update(j, f, 1, 0, c - 1, y1, y2, v);
            }
            else {
                p.SUM = p.MAX = 0, p.MIN = INF;
                for(int j = x1; j <= x2; ++ j) query(j, 1, 0, c - 1, y1, y2);
                printf("%d %d %d\n", p.SUM, p.MIN, p.MAX);
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值