封装一个线段树包含
维护信息,标记,maintain,pushdown,update,query操作
#include<bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N=1<<18;
const int inf=1e9+5;
int _max,_sum,_min,op,x,y,x2,y2,v,r,c,m,i,j;
struct tree{
int sum[N],maxx[N],minn[N],add_tag[N],set_tag[N];
void maintain(int p,int l ,int r)
{
if(r>l)
{
sum[p]=sum[ls]+sum[rs];
maxx[p]=max(maxx[ls],maxx[rs]);
minn[p]=min(minn[ls],minn[rs]);
}
if(set_tag[p]!=-1)
{
maxx[p]=set_tag[p],minn[p]=set_tag[p],sum[p]=set_tag[p]*(r-l+1);
}
if(add_tag[p])
{
minn[p]+=add_tag[p];
maxx[p]+=add_tag[p];
sum[p]+=add_tag[p]*(r-l+1);
}
}
void push_down(int p)
{
if(set_tag[p]!=-1)
{
set_tag[ls]=set_tag[rs]=set_tag[p];
add_tag[ls]=add_tag[rs]=0;
set_tag[p]=-1;
}
if(add_tag[p])
{
add_tag[ls]+=add_tag[p];
add_tag[rs]+=add_tag[p];
add_tag[p]=0;
}
}
void update(int p,int l,int r)
{
if(y<=l&&r<=y2)
{
if(op==1)
add_tag[p]+=v;
else add_tag[p]=0,set_tag[p]=v;
}
else {
push_down(p);
int m=(l+r)>>1;
if(y<=m) update(ls,l,m);
else maintain(ls,l,m);
if(y2>m) update(rs,m+1,r);
else maintain(rs,m+1,r);
}
maintain(p,l,r);
}
void queryy(int p,int l,int r,int& ssum,int& smin,int& smax)
{
maintain(p,l,r);
if(y<=l&&r<=y2)
{
ssum=sum[p];
smax=maxx[p];
smin=minn[p];
}
else {
push_down(p);
int m=(l+r)>>1;
int lsum=0,lmin=inf,lmax=-inf;
int rsum=0,rmin=inf,rmax=-inf;
if(y<=m)
queryy(ls,l,m,lsum,lmin,lmax);
else maintain(ls,l,m);
if(y2>m)
queryy(rs,m+1,r,rsum,rmin,rmax);
else maintain(rs,m+1,r);
ssum=lsum+rsum;
smin=min(lmin,rmin);
smax=max(lmax,rmax);
}
}
}trees[21];
int main ()
{
while(scanf("%d%d%d",&r,&c,&m)==3)
{
memset(trees,0,sizeof(trees));
for(i=1;i<=r;++i)
{
memset(trees[i].set_tag,-1,sizeof(trees[i].set_tag));
trees[i].set_tag[1]=0;
}
for(i=1;i<=m;++i)
{
scanf("%d%d%d%d%d",&op,&x,&y,&x2,&y2);
if(op!=3)
{
scanf("%d",&v);
for(j=x;j<=x2;++j)
{
trees[j].update(1,1,c);
}
}
else {
_max=-inf;
_min=inf;
_sum=0;
int gmax=-inf,gmin=inf,gsum=0;
for(j=x;j<=x2;++j)
{
trees[j].queryy(1,1,c,_sum,_min,_max);
gsum+=_sum;
gmax=max(_max,gmax);
gmin=min(_min,gmin);
_sum=0,_max=-inf,_min=inf;
}
printf("%d %d %d\n",gsum,gmin,gmax);
}
}
}
return 0;
}