题意:有一个行r,列c的矩阵的初始值都为0,然后有三种操作,子矩阵(x1,y1,x2,y2)全部元素都增加v或置为v,或者查询这个子矩阵的元素和、最大值、最小值。
题解:区间修改模板题,把每行当做一个线段树。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 50000 * 4;
const int INF = 0x3f3f3f3f;
int r, c, q, op, x1, x2, y1, y2, v;
int summ, minn, maxx;
struct Node {
int sum[N], mi[N], ma[N], addv[N], setv[N];
void pushup(int k, int left, int right) {
int lc = k * 2, rc = k * 2 + 1;
if (right > left) {
sum[k] = sum[lc] + sum[rc];
mi[k] = min(mi[lc], mi[rc]);
ma[k] = max(ma[lc], ma[rc]);
}
if (setv[k] >= 0) {
mi[k] = ma[k] = setv[k];
sum[k] = setv[k] * (right - left + 1);
}
if (addv[k]) {
mi[k] += addv[k];
ma[k] += addv[k];
sum[k] += addv[k] * (right - left + 1);
}
}
void pushdown(int k) {
int lc = k * 2, rc = k * 2 + 1;
if (setv[k] >= 0) {
setv[lc] = setv[rc] = setv[k];
addv[lc] = addv[rc] = 0;
setv[k] = -1;
}
if (addv[k]) {
addv[lc] += addv[k];
addv[rc] += addv[k];
addv[k] = 0;
}
}
void update(int k, int left, int right) {
int lc = k * 2, rc = k * 2 + 1;
if (y1 <= left && right <= y2) {
if (op == 1)
addv[k] += v;
else {
setv[k] = v;
addv[k] = 0;
}
}
else {
pushdown(k);
int mid = (left + right) / 2;
if (y1 <= mid)
update(lc, left, mid);
else
pushup(lc, left, mid);
if (mid < y2)
update(rc, mid + 1, right);
else
pushup(rc, mid + 1, right);
}
pushup(k, left, right);
}
void query(int k, int left, int right, int add) {
if (setv[k] >= 0) {
int v = setv[k] + add + addv[k];
summ += v * (min(right, y2) - max(left, y1) + 1);
minn = min(minn, v);
maxx = max(maxx, v);
}
else if (y1 <= left && right <= y2) {
summ += sum[k] + add * (right - left + 1);
minn = min(minn, mi[k] + add);
maxx = max(maxx, ma[k] + add);
}
else {
int mid = (left + right) / 2;
if (y1 <= mid)
query(k * 2, left, mid, add + addv[k]);
if (y2 > mid)
query(k * 2 + 1, mid + 1, right, add + addv[k]);
}
}
}node[22];
void init() {
for (int i = 1; i <= r; i++) {
memset(node[i].sum, 0, sizeof(node[i].sum));
memset(node[i].mi, 0, sizeof(node[i].mi));
memset(node[i].ma, 0, sizeof(node[i].ma));
memset(node[i].addv, 0, sizeof(node[i].addv));
memset(node[i].setv, -1, sizeof(node[i].setv));
node[i].setv[1] = 0;
}
}
int main() {
while (scanf("%d%d%d", &r, &c, &q) == 3) {
init();
while (q--) {
scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
if (op < 3) {
scanf("%d", &v);
for (int i = x1; i <= x2; i++)
node[i].update(1, 1, c);
}
else {
summ = 0, minn = INF, maxx = -INF;
for (int i = x1; i <= x2; i++)
node[i].query(1, 1, c, 0);
printf("%d %d %d\n", summ, minn, maxx);
}
}
}
return 0;
}原文:http://blog.csdn.net/hyczms/article/details/44907917