码迷,mamicode.com
首页 > 其他好文 > 详细

uva 11992(线段树)

时间:2015-04-07 09:49:28      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:uva   线段树   数据结构   

题意:有一个行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;
}

uva 11992(线段树)

标签:uva   线段树   数据结构   

原文地址:http://blog.csdn.net/hyczms/article/details/44907917

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!