对矩阵操作我们容易想到二维线段树或者二维树状数组
但是这题不需要二维 由于r<=20 所以我们开20个线段树就可以记录了 不过要注意一下set和add的先后顺序即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
#include <queue>
#include <map>
#include <sstream>
#include <set>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 100005;
int add[25][MAX_N<<1],col[25][MAX_N<<1],s[25][MAX_N<<1],minn[25][MAX_N<<1],maxx[25][MAX_N<<1];
void up(int p,int rt){
s[p][rt] = s[p][rt<<1] + s[p][rt<<1|1];
maxx[p][rt] = max(maxx[p][rt<<1],maxx[p][rt<<1|1]);
minn[p][rt] = min(minn[p][rt<<1],minn[p][rt<<1|1]);
}
void build(int p,int rt,int l,int r){
col[p][rt] = add[p][rt] = 0;
if(l==r){
s[p][rt] =maxx[p][rt] = minn[p][rt] = 0;
return;
}
int mid = (l+r)>>1;
build(p,rt<<1,l,mid);
build(p,rt<<1|1,mid+1,r);
}
void down(int p,int rt,int l,int r){
int mid = (l+r)>>1;
if(col[p][rt]){
col[p][rt<<1] = col[p][rt];
maxx[p][rt<<1] = col[p][rt];
minn[p][rt<<1] = col[p][rt];
s[p][rt<<1] = (mid-l+1)*col[p][rt];
add[p][rt<<1] = 0;
col[p][rt<<1|1] = col[p][rt];
maxx[p][rt<<1|1] = col[p][rt];
minn[p][rt<<1|1] = col[p][rt];
s[p][rt<<1|1] = (r-mid)*col[p][rt];
add[p][rt<<1|1] = 0;
col[p][rt] = 0;
}
if(add[p][rt]){
add[p][rt<<1] += add[p][rt];
minn[p][rt<<1]+=add[p][rt];
maxx[p][rt<<1]+=add[p][rt];
s[p][rt<<1] += add[p][rt]*(mid-l+1);
add[p][rt<<1|1] += add[p][rt];
minn[p][rt<<1|1] += add[p][rt];
maxx[p][rt<<1|1] += add[p][rt];
s[p][rt<<1|1] += add[p][rt]*(r-mid);
add[p][rt] = 0;
}
}
void modify(int opt,int p,int rt,int l,int r,int x,int y,int v){
if(opt==1){
if(x<=l&&r<=y){
add[p][rt] += v;
maxx[p][rt] += v;
minn[p][rt] += v;
s[p][rt] += (r-l+1)*v;
return ;
}
int mid = (l+r)>>1;
down(p,rt,l,r);
if(x<=mid) modify(opt,p,rt<<1,l,mid,x,y,v);
if(mid<y) modify(opt,p,rt<<1|1,mid+1,r,x,y,v);
up(p,rt);
}
else {
if(x<=l&&r<=y){
col[p][rt] = v;
minn[p][rt] = v;
maxx[p][rt] = v;
s[p][rt] = (r-l+1)*v;
add[p][rt] = 0;
return ;
}
int mid = (l+r)>>1;
down(p,rt,l,r);
if(x<=mid) modify(opt,p,rt<<1,l,mid,x,y,v);
if(mid<y) modify(opt,p,rt<<1|1,mid+1,r,x,y,v);
up(p,rt);
}
}
int query(int p,int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
return maxx[p][rt];
}
int mid = (l+r)>>1;
down(p,rt,l,r);
int maxx1 = 0,maxx2 = 0;
if(x<=mid) maxx1 = query(p,rt<<1,l,mid,x,y);
if(mid<y) maxx2 = query(p,rt<<1|1,mid+1,r,x,y);
return max(maxx1,maxx2);
}
int query_(int p,int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
return minn[p][rt];
}
int mid = (l+r)>>1;
down(p,rt,l,r);
int minn1 = 0x3f3f3f3f,minn2 = 0x3f3f3f3f;
if(x<=mid) minn1 = query_(p,rt<<1,l,mid,x,y);
if(mid<y) minn2 = query_(p,rt<<1|1,mid+1,r,x,y);
return min(minn1,minn2);
}
int query_sum(int p,int rt,int l,int r,int x,int y){
if(x<=l&&r<=y)
return s[p][rt];
int mid = (l+r)>>1;
down(p,rt,l,r);
int sum = 0;
if(x<=mid) sum+=query_sum(p,rt<<1,l,mid,x,y);
if(mid<y) sum+=query_sum(p,rt<<1|1,mid+1,r,x,y);
return sum;
}
int ansmin,ansmax,anssum;
void Query(int p,int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
ansmin = min(ansmin,minn[p][rt]);
ansmax = max(ansmax,maxx[p][rt]);
anssum += s[p][rt];
return ;
}
down(p,rt,l,r);
int mid = (l+r)>>1;
if(x<=mid) Query(p,rt<<1,l,mid,x,y);
if(mid<y) Query(p,rt<<1|1,mid+1,r,x,y);
}
int main(){
int n,m,q;
while(scanf("%d%d%d",&n,&m,&q)==3){
for(int i = 1;i<=n;++i)
build(i,1,1,m);
while(q--){
int opt,a,b,c,d,v;
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%d%d%d",&a,&b,&c,&d,&v);
for(int i = a;i<=c;++i)
modify(opt,i,1,1,m,b,d,v);
}
else if(opt==2){
scanf("%d%d%d%d%d",&a,&b,&c,&d,&v);
for(int i = a;i<=c;++i)
modify(opt,i,1,1,m,b,d,v);
}
else if(opt==3){
scanf("%d%d%d%d",&a,&b,&c,&d);
//ansmin= 0x3f3f3f3f,ansmax = 0,anssum = 0;
int a_maxx = 0,a_minn = 0x3f3f3f3f,a_sum = 0;
for(int i = a;i<=c;++i){
a_maxx = max(a_maxx,query(i,1,1,m,b,d));
a_minn = min(a_minn,query_(i,1,1,m,b,d));
a_sum+=query_sum(i,1,1,m,b,d);
//Query(i,1,1,m,b,d);
}
printf("%d %d %d\n",a_sum,a_minn,a_maxx);
}
}
}
return 0;
}