#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;
}
uva11992
最新推荐文章于 2024-07-30 18:55:53 发布