典型线段树,由于是初学,写错了很多很多东西
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cmath>
#include <vector>
#include <deque>
#include <algorithm>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define REP(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<=(n);i++)
#define FOR(i,a,b) for (int i=(a);i<=(b);i++)
#define CLR(x,n) memset(x,n,sizeof(x))
#define PN printf("\n")
#define read(x) scanf("%d",&x)
#define read2(x,y) scanf("%d%d",&x,&y)
#define read3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define write(x) printf("%d",x)
#define write1(x) printf("%d ",x)
#define writeln(x) printf("%d\n",x)
#define write2(x,y) printf("%d %d",x,y)
#define writeln2(x,y) printf("%d %d\n",x,y)
#define write3(x,y,z) printf("%d %d %d",x,y,z)
#define writeln3(x,y,z) printf("%d %d %d\n",x,y,z)
#define delta 1e-5
#define INF 0x7FFFFFFF
using namespace std;
/*
add出现负数,原来是pushdown里把addv设成了-1
此外 pushdown中打错一个setv[2*o]=-1;
pushdown中出现致命错误 addv[2*o]=addv[2*o+1]=addv[o] 应该用+=
还是不对 add操作边界条件进去应该addv[o]+= 而不是=
query的add也要注意
又写错一处 setv[o]>=0 里面的 运算 应该要带max min
对拍的时候发现一处错误 maintain中要把信息清零
碰到致命问题 把1-8set为1 再 add 8 8 1 那么查8的时候会出问题
只好在add中仿照 set进行pushdown
拍了好久 又发现问题 query里即使setv>=0也要考虑add
又有问题 add多次再set值会很大 因为set往下传的时候下面的add值还在
所以如果setv>0要把儿子的addv清零
*/
const int maxn=1<<17;
int r,c,m,op,_sum,_min,_max,x1,x2,Y1,Y2,v;
int addv[22][2*maxn],sumv[22][2*maxn],maxv[22][2*maxn],minv[22][2*maxn],setv[22][2*maxn];
void query(int t,int o,int l,int r,int add){
if (setv[t][o]>=0){
_sum+=(setv[t][o]+addv[t][o])*(min(r,Y2)-max(l,Y1)+1);
_sum+=add*(min(r,Y2)-max(l,Y1)+1);
_max=max(_max,setv[t][o]+addv[t][o]+add);
_min=min(_min,setv[t][o]+addv[t][o]+add);
}else if (Y1<=l && r<=Y2){
_sum+=sumv[t][o]+add*(r-l+1);
_max=max(_max,maxv[t][o]+add);
_min=min(_min,minv[t][o]+add);
}else {
int m=(l+r)/2;
if (Y1<=m) query(t,2*o,l,m,add+addv[t][o]);
if (Y2>m) query(t,2*o+1,m+1,r,add+addv[t][o]);
}
}
void maintain(int t,int o,int l,int r){
sumv[t][o]=maxv[t][o]=minv[t][o]=0;
if (r>l){
sumv[t][o]=sumv[t][2*o]+sumv[t][2*o+1];
maxv[t][o]=max(maxv[t][2*o],maxv[t][2*o+1]);
minv[t][o]=min(minv[t][2*o],minv[t][2*o+1]);
}
if (setv[t][o]>=0) {
sumv[t][o]=setv[t][o]*(r-l+1);
maxv[t][o]=setv[t][o];
minv[t][o]=setv[t][o];
}
sumv[t][o]+=addv[t][o]*(r-l+1); maxv[t][o]+=addv[t][o];minv[t][o]+=addv[t][o];
}
void pushdown(int t,int o){
if (setv[t][o]>=0){
setv[t][2*o]=setv[t][2*o+1]=setv[t][o];
setv[t][o]=-1;
addv[t][2*o]=addv[t][2*o+1]=0;
}
addv[t][2*o]+=addv[t][o];
addv[t][2*o+1]+=addv[t][o];
addv[t][o]=0;
}
void add(int t,int o,int l,int r){
if(Y1<=l && r<=Y2)
addv[t][o]+=v;
else {
pushdown(t,o);
int m=l+(r-l)/2;
if (Y1<=m) add(t,2*o,l,m);else maintain(t,2*o,l,m);
if (m<Y2) add(t,2*o+1,m+1,r);else maintain(t,2*o+1,m+1,r);
}
maintain(t,o,l,r);
}
void set1(int t,int o,int l,int r){
if (Y1<=l && r<=Y2){
setv[t][o]=v;
addv[t][o]=0;
}
else {
pushdown(t,o);
int m=l+(r-l)/2;
if (Y1<=m) set1(t,2*o,l,m); else maintain(t,2*o,l,m);
if (Y2>m) set1(t,2*o+1,m+1,r); else maintain(t,2*o+1,m+1,r);
}
maintain(t,o,l,r);
}
void print(){
REP(i,2*maxn)printf("%d %d %d %d %d %d\n",i,sumv[6][i],maxv[6][i],minv[6][i],addv[6][i],setv[6][i]);
}
int main(){
read3(r,c,m);CLR(setv,-1);CLR(addv,0);
REP(i,m){
read(op);
if (op==1){
scanf("%d%d%d%d%d",&x1,&Y1,&x2,&Y2,&v);
FOR(i,x1,x2)add(i,1,1,maxn);
}else if (op==2){
scanf("%d%d%d%d%d",&x1,&Y1,&x2,&Y2,&v);
FOR(i,x1,x2)set1(i,1,1,maxn);
}else {
scanf("%d%d%d%d",&x1,&Y1,&x2,&Y2);
_sum=0;_max=-INF;_min=INF;
FOR(i,x1,x2){query(i,1,1,maxn,0);}
printf("%d %d %d\n",_sum,_min,_max);
}
//print();PN;
}
return 0;
}