题意:给一个r行c列的矩阵(r<=20,r*l<=1e6),初始化都为0,三种操作:
1 r1 c1 r2 c2 v 把矩阵(r1,c1)到(r2,c2)的元素全加上v
2 r1 c1 r2 c2 v 把矩阵(r1,c1)到(r2,c2)的元素全变成v
3 r1 c1 r2 c2 求矩阵(r1,c1)到(r2,c2)的元素的和、最小值、最大值
这道题简直就是为了让我们写一个线段树基础问题的全能模板啊。。。
也就是 区间双更新(都加上v、都变成v)区间三查询(和、最小值、最大值)模板。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=4000010;
struct node{
int addv,setv;
int sum,ma,mi;
};
int ans,mi,ma,ql,qr;
int x1,x2,v;
struct xds{
node a[maxn];
void build(int i,int l,int r)
{
a[i].sum=a[i].ma=a[i].mi=a[i].setv=a[i].addv=0;
if(l==r)return;
else
{
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
}
}
void pushup(int i)
{
a[i].sum=a[i*2].sum+a[i*2+1].sum;
a[i].ma=max(a[i*2].ma,a[i*2+1].ma);
a[i].mi=min(a[i*2].mi,a[i*2+1].mi);
}
void pushdown(int i,int l,int r)
{
if(a[i].setv)
{
int x=a[i].setv;
int mid=(l+r)>>1;
a[i*2].setv=a[i*2+1].setv=x;
a[i*2].mi=a[i*2+1].mi=x;
a[i*2].ma=a[i*2+1].ma=x;
a[i*2].sum=(mid-l+1)*x;
a[i*2+1].sum=(r-mid)*x;
a[i].setv=a[i*2].addv=a[i*2+1].addv=0;
}
if(a[i].addv)
{
int x=a[i].addv;
int mid=(l+r)>>1;
a[i*2].addv+=x;a[i*2+1].addv+=x;
a[i*2].mi+=x;a[i*2+1].mi+=x;
a[i*2].ma+=x;a[i*2+1].ma+=x;
a[i*2].sum+=(mid-l+1)*x;
a[i*2+1].sum+=(r-mid)*x;
a[i].addv=0;
}
}
void update(int i,int l,int r,int id)
{
if(x1<=l&&x2>=r)
{
if(id==1)
{
a[i].addv+=v;
a[i].mi+=v;
a[i].ma+=v;
a[i].sum+=(r-l+1)*v;
}
else
{
a[i].addv=0;
a[i].setv=v;
a[i].mi=v;
a[i].ma=v;
a[i].sum=(r-l+1)*v;
}
return;
}
pushdown(i,l,r);
int mid=(l+r)>>1;
if(x1<=mid) update(i*2,l,mid,id);
if(x2>mid) update(i*2+1,mid+1,r,id);
pushup(i);
}
void query(int i,int l,int r)
{
if(ql<=l&&qr>=r)
{
ans+=a[i].sum;
ma=max(ma,a[i].ma);
mi=min(mi,a[i].mi);
return;
}
pushdown(i,l,r);
int mid=(l+r)>>1;
if(ql<=mid) query(i*2,l,mid);
if(qr>mid) query(i*2+1,mid+1,r);
}
}shu[25];
int n,m,k,q;
int b[maxn],tmp,cnt;
int main()
{
//ios::sync_with_stdio(false);
int flag;
int T;
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
for(int i=1;i<=n;i++)
{
shu[i].build(1,1,m);
}
while(q--)
{
int id;
scanf("%d",&id);
if(id==3){
int aa,bb;
ans=0;mi=inf;ma=-inf;
scanf("%d%d%d%d",&aa,&ql,&bb,&qr);
for(int j=aa;j<=bb;j++)
{
shu[j].query(1,1,m);
}
printf("%d %d %d\n",ans,mi,ma);
}
else
{
int aa,bb;
scanf("%d%d%d%d%d",&aa,&x1,&bb,&x2,&v);
for(int j=aa;j<=bb;j++)
shu[j].update(1,1,m,id);
}
}
}
return 0;
}