程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> uva 11992(線段樹)

uva 11992(線段樹)

編輯:關於C++

題意:有一個行r,列c的矩陣的初始值都為0,然後有三種操作,子矩陣(x1,y1,x2,y2)全部元素都增加v或置為v,或者查詢這個子矩陣的元素和、最大值、最小值。

題解:區間修改模板題,把每行當做一個線段樹。

 

#include 
#include 
#include 
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;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved