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;
}
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;
}
相关文章推荐
- 1.10055 - Hashmat the brave warrior
- 2.10071 - Back to High School Physics
- 3.458 - The Decoder
- 4.694 - The Collatz Sequence
- 6.494 - Kindergarten Counting Game
- 7.490 - Rotating Sentences
- 8.414 - Machined Surfaces
- 9.488 - Triangle Wave
- A.457 - Linear Cellular Automata
- B.489 - Hangman Judge
- C.445 - Marvelous Mazes
- 1.10494 - If We Were a Child Again
- 2.424 - Integer Inquiry
- 3.10250 - The Other Two Trees
- 5.465 - Overflow
- 6.113 - Power of Cryptography
- 7.10161 - Ant on a Chessboard
- 8.621 - Secret Research
- 9.401 - Palindromes
- A.537 - Artificial Intelligence?