题意:给一个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; }