模板题:区间更新 、查询.
看似简单,但敲出来漏洞百出。。。 还是对线段树不熟悉。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 3000000+50 ; // 要开3倍 ,2被会wa ,很奇怪。
const int INF = 1e9;
#define Lson o<<1 , L , mid
#define Rson o<<1|1, mid+1 , R
#define clr(a , b) memset(a , 0 , (b)*sizeof(a[0]))
struct segment_tree{
int sum[maxn] , ma[maxn] , mi[maxn] ,st[maxn], add[maxn] ;
void Build(int n){
clr(sum , n*3+10),clr(ma , n*3+10),clr(mi , n*3+10),clr(add , n*3+10);
memset(st , -1, (n*3+10)*sizeof(st[0])) ;
}
inline void update(int o){
int lo = o<<1 , ro = o<<1|1 ;
sum[o] = sum[lo] + sum[ro] ;
ma[o] = max(ma[lo] , ma[ro]) ;
mi[o] = min(mi[lo] , mi[ro]) ;
}
inline void pushdown(int o,int L,int R){
int lo = o<<1 , ro = o<<1|1 ;
if(st[o] !=-1){
sum[o] = st[o] * (R-L+1) , ma[o] = st[o] , mi[o] = st[o] ;
if(L<R) st[lo] = st[ro] = st[o] , add[lo] = add[ro] = 0 ;
st[o] = -1 ;
}
if(add[o]){
sum[o] += add[o]*(R-L+1) , ma[o]+=add[o] , mi[o] += add[o] ;
if(L<R) add[lo]+=add[o] , add[ro]+=add[o] ;
add[o] = 0;
}
}
int sL , sR , sV ;
void Set(int o ,int L ,int R){
pushdown(o , L ,R) ;
int lo = o<<1 , ro = o<<1|1 , mid = (R+L)>>1 ;
if(sL <=L && R<=sR){
sum[o] = sV*(R-L+1) , ma[o] = sV , mi[o] = sV ;
if(L<R) pushdown(Lson) , pushdown(Rson) ,st[lo]=st[ro]=sV , add[lo]=add[ro]=0;
return ; // 更新节点信息前一定要先将节点原来的信息传递下去。
}
if(sL <= mid) Set(Lson); else pushdown(Lson) ;
if(sR > mid) Set(Rson) ; else pushdown(Rson) ;
update(o) ;
}
int aL , aR , aV ;
void Add(int o, int L , int R){
pushdown(o,L,R) ;
int lo=o<<1 , ro = o<<1|1 , mid = (L+R)>>1 ;
if(aL <=L && R<= aR){
sum[o]+=aV*(R-L+1) , ma[o]+=aV , mi[o]+=aV ;
if(L<R) pushdown(Lson) , pushdown(Rson) ,add[lo]+=aV , add[ro]+=aV;
return ; // 同上 ,需要注意!!
}
if(aL <= mid) Add(Lson); else pushdown(Lson) ; // 为使下面update不会出错. 本节点信息正确性依赖于儿子信息.
if(aR > mid) Add(Rson); else pushdown(Rson) ;
update(o) ;
}
int qL , qR , q_sum , q_max , q_min ;
void Query(int o , int L ,int R){
pushdown(o,L,R);
int mid = (L+R)>>1 ;
if(qL<=L && R<=qR) {
q_sum += sum[o] , q_max = max(q_max , ma[o]) , q_min = min(q_min , mi[o]) ;
return ;
}
if(qL<=mid) Query(Lson);
if(qR>mid) Query(Rson);
}
}T[22];
int main()
{
//freopen("in.txt","r",stdin);
int r ,n ,m ;
while(scanf("%d%d%d" , &r ,&n ,&m)==3){
for(int i=1; i<=r ;i++) T[i].Build(n);
int op , x1 , x2 , y1 ,y2, v;
while(m--){
scanf("%d %d %d %d %d", &op , &x1 ,&y1 , &x2 ,&y2) ;
if(op==1){
scanf("%d" , &v) ;
for(int i=x1; i<=x2; i++){
T[i].aL = y1 , T[i].aR = y2 ,T[i].aV = v;
T[i].Add(1,1,n);
}
} else if(op==2) {
scanf("%d" ,&v) ;
for(int i=x1; i<=x2 ;i++){
T[i].sL = y1 , T[i].sR = y2 ,T[i].sV = v ;
T[i].Set(1,1,n);
}
} else {
int ssum = 0 , mmax = -INF , mmin = INF ;
for(int i=x1; i<=x2; i++){
T[i].qL = y1 , T[i].qR = y2 , T[i].q_sum =0 , T[i].q_max=-INF , T[i].q_min = INF ;
T[i].Query(1,1,n);
ssum+=T[i].q_sum , mmax = max(mmax , T[i].q_max) , mmin = min(mmin , T[i].q_min);
}
printf("%d %d %d\n" ,ssum , mmin , mmax) ;
}
}
}
return 0;
}