题意:
三种操作在矩阵上进行。添加val,set val,查询。
分析:
裸线段树,但是做完后发现别人都用的一维的,而我却封装了用的二维的。。。。也是醉了,数据再大点的话就存不小来了。。也是侥幸啊。
建议大家还是用一维的好,每个点都是(x-1)*c+y。
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <fstream>
#include <math.h>
#include <iomanip>
#define read freopen("q.in","r",stdin)
#define write freopen("q.out","w",stdout)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<pii,int> PII;
typedef int ll;
const int maxn = 1000006;
const int maxv = 10000007;
const int inf = 99999999;
ll ansmin,ansmax;
struct Node
{
ll s,ma,mi;
Node(){s=ma=mi=0;}
Node(ll a,ll b,ll c)
{
s=a;ma=b;mi=c;
}
};
class ST
{
public:
ST(){};
~ST(){};
ll col[maxn<<2],add[maxn<<2],sum[maxn<<2],mmax[maxn<<2],mmin[maxn<<2];
void PushUp(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
mmax[rt]=max(mmax[rt<<1],mmax[rt<<1|1]);
mmin[rt]=min(mmin[rt<<1],mmin[rt<<1|1]);
}
void PushDown(int rt,int m)
{
if(col[rt]>=0)
{
col[rt<<1]=col[rt<<1|1]=col[rt];
sum[rt<<1]=(m-(m>>1))*col[rt];
sum[rt<<1|1]=(m>>1)*col[rt];
mmax[rt<<1]=mmax[rt<<1|1]=col[rt];
mmin[rt<<1]=mmin[rt<<1|1]=col[rt];
col[rt]=-1;
add[rt<<1]=add[rt<<1|1]=0;
}
if(add[rt])
{
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=(m-(m>>1))*add[rt];
sum[rt<<1|1]+=(m>>1)*add[rt];
mmax[rt<<1]+=add[rt];
mmax[rt<<1|1]+=add[rt];
mmin[rt<<1]+=add[rt];
mmin[rt<<1|1]+=add[rt];
add[rt]=0;
}
}
void build(int l,int r,int rt)
{
// col[rt]=0;
// sum[rt]=1;
if(l==r)
{
scanf("%I64d",&sum[rt]);
return ;
}
int mid=(l+r)/2;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
PushUp(rt);
}
void Build()
{
memset(col,-1,sizeof(col));
memset(add,0,sizeof(add));
memset(sum,0,sizeof(sum));
memset(mmax,0,sizeof(mmax));
memset(mmin,0,sizeof(mmin));
}
void Replace(int L,int R,int l,int r,int rt,ll c) // set 操作
{
if(L<=l && r<=R)
{
col[rt]=c;
add[rt]=0;
sum[rt]=(r-l+1)*c;
mmax[rt]=mmin[rt]=c;
return ;
}
PushDown(rt,r-l+1);
int mid=(r+l)>>1;
if(L<=mid)Replace(L,R,l,mid,rt<<1,c);
if(R>mid)Replace(L,R,mid+1,r,rt<<1|1,c);
PushUp(rt);
}
void Update(int L,int R,int l,int r,int rt,ll c)
{
if(L<=l && r<=R)
{
sum[rt]+=(r-l+1)*c;
mmax[rt]+=c;
mmin[rt]+=c;
add[rt]+=c;
return ;
}
PushDown(rt,r-l+1);
int mid=(r+l)>>1;
if(L<=mid)Update(L,R,l,mid,rt<<1,c);
if(R>mid)Update(L,R,mid+1,r,rt<<1|1,c);
PushUp(rt);
}
ll Query(int L,int R,int l,int r,int rt)
{
if(L<=l && r<=R)
{
ansmin=min(ansmin,mmin[rt]);
ansmax=max(ansmax,mmax[rt]);
return sum[rt];
}
PushDown(rt,r-l+1);
int mid=(r+l)>>1;
ll res=0;
if(L<=mid)res+=Query(L,R,l,mid,rt<<1);
if(R>mid)res+=Query(L,R,mid+1,r,rt<<1|1);
return res;
}
}bt[21];
int main()
{
// read;
int i,j,r,c,m;
while(~scanf("%d%d%d",&r,&c,&m))
{
int op,x1,x2,y1,y2;
ll val;
for(i=0;i<=r;i++)bt[i].Build();
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
for(i=x1;i<=x2;i++)
{
bt[i].Update(y1,y2,1,c,1,val);
}
}
else if(op==2)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
for(i=x1;i<=x2;i++)
{
bt[i].Replace(y1,y2,1,c,1,val);
}
}
else
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
ansmax=-1;ansmin=inf;
ll res=0;
for(i=x1;i<=x2;i++)
{
res+=bt[i].Query(y1,y2,1,c,1);
}
printf("%d %d %d\n",res,ansmin,ansmax);
}
}
}
}
;