您的位置:首页 > 运维架构

Uva 11992 Fast Matrix Operations (二维线段树)

2015-09-15 00:28 357 查看
Fast Matrix
Operations

题意: 给定一个r<=20 c<=10^6的全0矩阵

 op1: 子矩阵元素全部增加v

 op2: 子矩阵元素全部变成v

 op3: 查询子矩阵的元素和, 最小值, 最大值

分析: 二维线段树裸题啦~ 这个题对于回复状态非常不错哒, 几乎包含了一般线段树的所有情况

 要注意一下push_down的时候    setv的优先级大于addv    然后setv之后要把addv置0, update的时候也要注意这个

代码: HH版线段树 由于是二维的 我简单封装了一下 这样看起来好看

//
// Created by TaoSama on 2015-09-14
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e6 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int r, n, q;
int Sum, Max, Min;

#define root 1, n, 1
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

struct SegTree {
int sum[N << 2], maxv[N << 2], minv[N << 2], setv[N << 2], addv[N << 2];

void push_up(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
maxv[rt] = max(maxv[rt << 1], maxv[rt << 1 | 1]);
minv[rt] = min(minv[rt << 1], minv[rt << 1 | 1]);
}
void push_down(int rt, int m) {
if(setv[rt]) {
setv[rt << 1] = setv[rt << 1 | 1] = setv[rt];
addv[rt << 1] = addv[rt << 1 | 1] = 0;
sum[rt << 1] = setv[rt] * (m - (m >> 1));
sum[rt << 1 | 1] = setv[rt] * (m >> 1);
maxv[rt << 1] = maxv[rt << 1 | 1] = setv[rt];
minv[rt << 1] = minv[rt << 1 | 1] = setv[rt];
setv[rt] = 0;
}
if(addv[rt]) {
addv[rt << 1] += addv[rt];
addv[rt << 1 | 1] += addv[rt];
sum[rt << 1] += addv[rt] * (m - (m >> 1));
sum[rt << 1 | 1] += addv[rt] * (m >> 1);
maxv[rt << 1] += addv[rt];
maxv[rt << 1 | 1] += addv[rt];
minv[rt << 1] += addv[rt];
minv[rt << 1 | 1] += addv[rt];
addv[rt] = 0;
}
}
void update(int L, int R, int v, int op, int l, int r, int rt) {
if(L <= l && r <= R) {
if(op == 2) {
setv[rt] = v;
addv[rt] = 0;
sum[rt] = (r - l + 1) * v;
maxv[rt] = minv[rt] = v;
} else {
addv[rt] += v;
sum[rt] += (r - l + 1) * v;
maxv[rt] += v, minv[rt] += v;
}
return;
}
int m = l + r >> 1;
push_down(rt, r - l + 1);
if(L <= m) update(L, R, v, op, lson);
if(R > m) update(L, R, v, op, rson);
push_up(rt);
}
void query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
Sum += sum[rt];
Min = min(Min, minv[rt]);
Max = max(Max, maxv[rt]);
return;
}
int m = l + r >> 1;
push_down(rt, r - l + 1);
if(L <= m) query(L, R, lson);
if(R > m) query(L, R, rson);
}
} T[21];

int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);

while(scanf("%d%d%d", &r, &n, &q) == 3) {
memset(T, 0, sizeof T);
while(q--) {
int op, x1, x2, y1, y2, v;
scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
if(op <= 2) {
scanf("%d", &v);
for(int i = x1; i <= x2; ++i)
T[i].update(y1, y2, v, op, root);
} else {
Sum = 0; Max = -INF; Min = INF;
for(int i = x1; i <= x2; ++i)
T[i].query(y1, y2, root);
printf("%d %d %d\n", Sum, Min, Max);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  UVA 11992 线段树