uva11992

#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>


#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;

const int maxn = 1e7 +7, INF = 1e9 + 7;
int r, c, m;

struct SegRet {
	SegRet() {
		m_sum = 0;
		m_max = -INF;
		m_min = INF;
	}
	int m_sum;
	int m_max;
	int m_min;
};
struct SegNode {
	int m_sum;
	int m_min;
	int m_max;
	int m_flag;
	int m_add;
	int m_set;
};

class SegmentTree {
public:
	void build(int cnt) {
		int len = (cnt << 2);
		int c = min(len * 2 + 1, maxn << 2);
		memset(m_node, 0, sizeof(SegNode) * c);
		m_first = 1;
		m_last = len;
	}

	void Push_Down(int cur, int len) {
		if (m_node[cur].m_flag == 0) return;
		int left = cur * 2, right = left + 1;
		//set
		if (m_node[cur].m_flag & 1) {
			int value = m_node[cur].m_set;
			m_node[left].m_flag = 1;
			m_node[left].m_add = 0;
			m_node[left].m_set = value;
			m_node[left].m_sum = (len - len / 2) * value;

			m_node[right].m_flag = 1;
			m_node[right].m_add = 0;
			m_node[right].m_set = value;
			m_node[right].m_sum = (len / 2) * value;

			m_node[left].m_min = m_node[left].m_max = m_node[right].m_min = m_node[right].m_max = value;
		}
		//add
		if (m_node[cur].m_flag & 2) {
			int value = m_node[cur].m_add;
			m_node[left].m_flag |= 2;
			m_node[left].m_add += value;
			m_node[left].m_sum += (len - len / 2) * value;

			m_node[right].m_flag |= 2;
			m_node[right].m_add += value;
			m_node[right].m_sum += (len / 2) * value;

			m_node[left].m_min += value;
			m_node[left].m_max += value;

			m_node[right].m_min += value;
			m_node[right].m_max += value;
		}
		m_node[cur].m_flag = m_node[cur].m_add = m_node[cur].m_set =  0;
	}

	void _Add(int left, int right, int val, int l, int r, int cur) {
		if (l > right || r < left) return;
		if (l >= left && r <= right) {
			m_node[cur].m_flag |= 2;
			m_node[cur].m_add += val;
			m_node[cur].m_sum += val * (r - l + 1);

			m_node[cur].m_max += val;
			m_node[cur].m_min += val;
			
			return;
		}
		Push_Down(cur, r - l + 1);

		int mid = (l + r) >> 1;
		if (mid >= left) {
			_Add(left, right, val, l, mid, cur * 2);
		}
		if (mid < right) {
			_Add(left, right, val, mid + 1, r, cur * 2 + 1);
		}
		int lc = cur * 2, rc = lc + 1;
		m_node[cur].m_max = max(m_node[lc].m_max, m_node[rc].m_max);
		m_node[cur].m_min = min(m_node[lc].m_min, m_node[rc].m_min);
		m_node[cur].m_sum = m_node[lc].m_sum + m_node[rc].m_sum;
	}
	void Add(int left, int right, int val) {
		_Add(left, right, val, m_first, m_last, 1);
	}

	void _Set(int left, int right, int val, int l, int r, int cur) {
		if (l > right || r < left) return;
		if (l >= left && r <= right) {
			m_node[cur].m_flag = 1;
			m_node[cur].m_add = 0;
			m_node[cur].m_set = val;
			m_node[cur].m_sum = (r - l + 1) * val;
			m_node[cur].m_max = val;
			m_node[cur].m_min = val;
			return;
		}
		Push_Down(cur, r - l + 1);

		int mid = (l + r) >> 1;
		if (mid >= left) {
			_Set(left, right, val, l, mid, cur * 2);
		}
		if (mid < right) {
			_Set(left, right, val, mid + 1, r, cur * 2 + 1);
		}
		int lc = cur * 2, rc = lc + 1;
		m_node[cur].m_max = max(m_node[lc].m_max, m_node[rc].m_max);
		m_node[cur].m_min = min(m_node[lc].m_min, m_node[rc].m_min);
		m_node[cur].m_sum = m_node[lc].m_sum + m_node[rc].m_sum;
	}
	void Set(int left, int right, int val) {
		_Set(left, right, val, m_first, m_last, 1);
	}
	SegRet _Query(int left, int right, int l, int r, int cur) {
		if (l > right || r < left) {
			SegRet ret;
			return ret;
		}
		if (l >= left && r <= right) {
			SegRet ret;
			ret.m_sum = m_node[cur].m_sum;
			ret.m_max = m_node[cur].m_max;
			ret.m_min = m_node[cur].m_min;
			return ret;
		}
		Push_Down(cur, r - l + 1);
		int mid = (l + r) >> 1;
		SegRet ans;
		if (mid >= left) {
			SegRet lr = _Query(left, right, l, mid, cur * 2);
			ans.m_max = max(ans.m_max, lr.m_max);
			ans.m_min = min(ans.m_min, lr.m_min);
			ans.m_sum += lr.m_sum;
		}
		if (mid < right ) {
			SegRet rr = _Query(left, right, mid + 1, r, cur * 2 + 1);
			ans.m_max = max(ans.m_max, rr.m_max);
			ans.m_min = min(ans.m_min, rr.m_min);
			ans.m_sum += rr.m_sum;
		}
		return ans;
	}
	SegRet Query(int left, int right) {
		return _Query(left, right, m_first, m_last, 1);
	}
public:
	SegNode m_node[maxn << 2];
	int m_first, m_last;
};

SegRet SRCombine(SegRet& a, SegRet& b) {
	SegRet ans;
	ans.m_sum = a.m_sum + b.m_sum;
	ans.m_max = max(a.m_max, b.m_max);
	ans.m_min = min(a.m_min, b.m_min);
	return ans;
}
SegmentTree stree;

int main()
{
	while (cin >> r >> c >> m) {
		stree.build(r * c);
		int a, x1, y1, x2, y2, v;
		SegRet ans, tmp;
		for (int i = 0; i < m; i++) {
			cin >> a >>x1 >> y1 >> x2 >> y2;
			if (a == 1) {
				cin >> v;
				for (int j = x1; j <= x2; j++) {
					int t = (j - 1) * c;
					stree.Add(t + y1,t + y2, v);
				}
			}
			else if (a == 2) {
				cin >> v;
				for (int j = x1; j <= x2; j++) {
					int t = (j - 1) * c;
					stree.Set(t + y1,t +  y2, v);
				}
			}
			else if (a == 3) {
				ans.m_sum = 0;
				ans.m_max = -INF;
				ans.m_min = INF;
				for (int j = x1; j <= x2; j++) {
					int t = (j - 1) * c;
					tmp = stree.Query(t + y1,t +  y2);
					ans = SRCombine(ans, tmp);
				}
				cout << ans.m_sum << " " << ans.m_min << " " << ans.m_max  << endl;
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值