题意:
那就N*M矩阵。三个操作1、X1 ,x2,y1,y2,k把左上角(x1,y1)到右下角(x2 y2)包起来的矩形所有元素+k. 第二个操作 还是输入五个 是把这区间元素全部置为k。第三个 输入左上右下坐标。输出这个矩形内最大元素 最小元素 和sum
tip:
第一眼看上去,如果是一维的,那么线段树就是够了的。但是二维,可以选择二维线段树,但是没写过233.
最开始被引导到分块,发现好像不太对QAQ,因为四周一圈都是要动的。
然后因为n*m是1e6的范围,就说明其中必有一个是小于1e3的,比如说是n,那么复杂度控制在n*logm*Q,Q是20000,就是说开了n个大小为m的线段树,这样比较方便写。。区间修改的时候,因为有置数的操作,那么在pushdown lazy标记的时候就比较麻烦,
首先关于update:当前区间是置数状态的时候,前面的add操作是没用的,如果在置数之后有对这个区间的add操作,那么add部分直接加到set上,就比如先置数为k再add m,那么直接置数k+m就好了,于是add只有再is_set为0,没有置数时才会被用到。
pushdown:这个时候先看是否置数了,
如果置数了,那么直接把两个儿子置数为改成这个值,然后自己的也清零,维护两个儿子最大最小和sum,(自己本身的再update时维护,因为pushdown是再不是整个区间的时候才走的,那么如果是整个区间,会直接return ,所以须在pushdown函数前维护好,就是update的时候直接维护了)。
如果没有置数,那么就是add了多少。这时候pushdown这个add要看,子区间是否处于set状态(wa了n小时),如果是set状态,那么这次的add还是要加在子区间的set上,如果子区间是add状态,直接加就好了,这个时候还是维护两个子区间的最大最小和sum就可以了,然后本区间置零。。。
关于开数组。。。vector,。。清零的时候要循环,不然只是清一维
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int N,M,Q,S1,S2,ty,x1,x2,y1,y2,v,S;
typedef pair<int , pair<int,int> > pii;
struct Tree{
int maxvalue,minvalue,sum;
};
vector <vector<Tree> >dytree;
vector <vector<int> >_set,add,is_set;
void push_up(int i,int rt){
dytree[i][rt].maxvalue = max(dytree[i][rt*2].maxvalue,dytree[i][rt*2+1].maxvalue);
dytree[i][rt].minvalue = min(dytree[i][rt*2].minvalue,dytree[i][rt*2+1].minvalue);
dytree[i][rt].sum = dytree[i][rt*2].sum+dytree[i][rt*2+1].sum;
}
void push_down(int i,int rt,int k){
if(is_set[i][rt]){
_set[i][rt*2] = _set[i][rt*2+1] = _set[i][rt];
is_set[i][rt*2] = is_set[i][rt*2+1] = 1;
add[i][rt] = add[i][rt*2] = add[i][rt*2+1] = 0;
dytree[i][rt*2].maxvalue = dytree[i][rt*2].minvalue = _set[i][rt];dytree[i][rt*2].sum = (k-(k>>1))*_set[i][rt];
dytree[i][rt*2+1].maxvalue = dytree[i][rt*2+1].minvalue = _set[i][rt];dytree[i][rt*2+1].sum = (k>>1)*_set[i][rt];
is_set[i][rt] = _set[i][rt] = 0;
}
else if(add[i][rt]){
int v = add[i][rt];
if(is_set[i][rt*2]){
_set[i][rt*2] += v;
add[i][rt*2] = 0;
dytree[i][rt*2].maxvalue = dytree[i][rt*2].minvalue = _set[i][rt*2];
dytree[i][rt*2].sum = (k-(k>>1))*_set[i][rt*2];
}
else{
add[i][rt*2] += v;
dytree[i][rt*2].maxvalue += v;
dytree[i][rt*2].minvalue += v;
dytree[i][rt*2].sum += (k-(k>>1))*v;
}
if(is_set[i][rt*2+1]){
_set[i][rt*2+1] += v;
add[i][rt*2+1] = 0;
dytree[i][rt*2+1].maxvalue = dytree[i][rt*2+1].minvalue = _set[i][rt*2+1];
dytree[i][rt*2+1].sum = (k>>1)*_set[i][rt*2+1];
}
else{
add[i][rt*2+1] += v;
dytree[i][rt*2+1].maxvalue += v;
dytree[i][rt*2+1].minvalue += v;
dytree[i][rt*2+1].sum += (k>>1)*v;
}
add[i][rt] = 0;
}
}
void update1(int i,int L,int R,int l,int r,int rt,int v){
if(L <= l && r <= R){
if(is_set[i][rt]){
_set[i][rt] += v;
add[i][rt] = 0;
dytree[i][rt].maxvalue = dytree[i][rt].minvalue = _set[i][rt];
dytree[i][rt].sum = (r-l+1)*_set[i][rt];
}
else{
add[i][rt] += v;
dytree[i][rt].maxvalue += v;
dytree[i][rt].minvalue += v;
dytree[i][rt].sum += (r-l+1)*v;
}
return;
}
push_down(i,rt,r-l+1);
int m=(l+r)>>1;
if(L <= m) update1(i,L,R,lson,v);
if(R > m) update1(i,L,R,rson,v);
push_up(i,rt);
}
void update2(int i,int L,int R,int l,int r,int rt,int v){
if(L <= l && r <= R){
_set[i][rt] = v;add[i][rt] = 0;is_set[i][rt] = 1;
dytree[i][rt].maxvalue = dytree[i][rt].minvalue = v;
dytree[i][rt].sum = (r-l+1)*v;
return;
}
push_down(i,rt,r-l+1);
int m=(l+r)>>1;
if(L <= m) update2(i,L,R,lson,v);
if(R > m) update2(i,L,R,rson,v);
push_up(i,rt);
}
pii query(int i,int L,int R,int l,int r,int rt){
if(l >= L && r <= R){
return make_pair(dytree[i][rt].maxvalue,make_pair(dytree[i][rt].minvalue,dytree[i][rt].sum));
}
push_down(i,rt,r-l+1);
int m=(l+r)>>1;
pii tmp,t1,ans;
t1.first = 0;t1.second.first = (1<<30) ; t1.second.second = 0;
tmp.first = 0;tmp.second.first = (1<<30) ; tmp.second.second = 0;ans.first = 0;ans.second.first = (1<<30) ; ans.second.second = 0;
if(L <= m)
tmp = query(i,L,R,lson);
if(R > m)
t1 = query(i,L,R,rson);
ans.first = max(tmp.first,t1.first);
ans.second.first = min(tmp.second.first,t1.second.first);
ans.second.second = tmp.second.second+t1.second.second;
return ans;
}
void ty1(int x1,int y1,int x2,int y2,int v){
//cout << "y1 = "<<y1<<" y2 = "<<y2<<" x1 = "<<x1 <<" x2 = "<<x2 <<endl;
for(int i = y1 ; i <= y2 ; i++){
update1(i,x1,x2,1,N,1,v);
}
}
void ty2(int x1,int y1,int x2,int y2,int v){
for(int i = y1 ; i <= y2 ; i++){
update2(i,x1,x2,1,N,1,v);
}
}
void ty3(int x1,int y1,int x2,int y2){
pii ans;
ans.first = 0;ans.second.first = (1<<30) ; ans.second.second = 0;
for(int i = y1 ; i <= y2 ; i++){
pii tmp = query(i,x1,x2,1,N,1);
//cout <<"check i : "<<i<<" max = "<<tmp.first<<" min - "<< tmp.second.first <<" sun = "<<tmp.second.second<<endl;
ans.first = max(ans.first,tmp.first);
ans.second.first = min(tmp.second.first,ans.second.first);
ans.second.second = tmp.second.second+ans.second.second;
}
printf("%d %d %d\n",ans.second.second,ans.second.first,ans.first);
}
void build(int i,int l,int r,int rt){
dytree[i][rt].maxvalue = dytree[i][rt].minvalue = dytree[i][rt].sum = 0;
if(l == r) return;
int m=(l+r)>>1;
build(i,lson);
build(i,rson);
}
void init(){
S = 0;
if (M > N){
swap(N,M);
S = 1;
}
S1 = M+10;S2 = 4*(N+10);
dytree.resize(S1,vector<Tree>(S2));
_set.resize(S1,vector<int>(S2));
is_set.resize(S1,vector<int>(S2));
add.resize(S1,vector<int>(S2));
for(int i = 1 ; i <= M ; i++){
build(i,1,N,1);
}
for(int i = 0 ; i <= M ; i++)
for(int j = 0 ; j <= 4*N ; j++)
_set[i][j] = add[i][j] = is_set[i][j]= 0;
}
void sov(){
for(int i = 0 ;i < Q ; i++){
scanf("%d",&ty);
if(ty == 1){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v);
if(S){
swap(x1,y1);
swap(x2,y2);
}
ty1(x1,y1,x2,y2,v);
}
else if(ty == 2){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v);
if(S){
swap(x1,y1);
swap(x2,y2);
}
ty2(x1,y1,x2,y2,v);
}
else if(ty == 3){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(S){
swap(x1,y1);
swap(x2,y2);
}
ty3(x1,y1,x2,y2);
}
// if(i == 4)
// cout <<": "<< dytree[2][2].minvalue << " "<<dytree[2][3].minvalue<<" "<<dytree[2][4].minvalue<<" "<<dytree[2][5].minvalue<<" "<<dytree[2][6].minvalue<<endl;
}
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d%d",&N,&M,&Q)){
init();
sov();
}
}
/*
15 17 12
2 4 6 14 8 54
1 7 4 13 11 46
1 8 10 14 15 67
1 2 3 13 10 21
3 2 10 14 15
2 7 7 15 11 32
1 6 2 14 14 59
2 9 7 15 14 71
2 5 8 11 12 92
2 5 8 14 15 59
2 6 1 13 4 64
3 6 1 14 10
15 17 4
1 4 6 14 8 54
1 6 2 14 14 59
1 9 7 15 14 71
3 6 1 14 10
*/