uva 11992

题意:

给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作。

1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val;

2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val;

3 x1 y1 x2 y2 val 表示输出(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素的sum,最大最小值

链接:

https://vjudge.net/contest/203644#problem/B

题解:

显然这两个操作是可以用线段树来维护的,但关键在于二维

注意到n<=20 ,所以可以考虑对每一行对列进行线段树维护

另外修改为v和增加v两个操作的同时存在

要注意:修改为v要清空增加v 并且先处理修改为v后处理增加v

代码:

#include <bits/stdc++.h>
#define mid (h+t)/2
using namespace std;
struct re{int a,b,c;} tmp;
struct ree{int h,t,x1,x2,x3,lazy1,lazy2;}p[22][300000];
void build(int hh,int x,int h,int t)
{  
  p[hh][x].h=h; p[hh][x].t=t; p[hh][x].x3=0;
  if (h==t) 
    {
        return;
  }
  build(hh,x*2,h,mid); build(hh,x*2+1,mid+1,t);
};
void down(int hh,int x)
{
    if (p[hh][x].lazy2!=0) 
    {
      p[hh][x].x1=(p[hh][x].t-p[hh][x].h+1)*p[hh][x].lazy2;
      p[hh][x].x2=p[hh][x].lazy2;
      p[hh][x].x3=p[hh][x].lazy2;
      p[hh][x*2].lazy2=p[hh][x].lazy2;
      p[hh][x*2+1].lazy2=p[hh][x].lazy2;
      p[hh][x*2].lazy1=p[hh][x*2+1].lazy1=0; 
      p[hh][x].lazy2=0;
  }
  p[hh][x].x1+=(p[hh][x].t-p[hh][x].h+1)*p[hh][x].lazy1;
  p[hh][x].x2+=p[hh][x].lazy1;
  p[hh][x].x3+=p[hh][x].lazy1;
  p[hh][x*2].lazy1+=p[hh][x].lazy1;
  p[hh][x*2+1].lazy1+=p[hh][x].lazy1;
  p[hh][x].lazy1=0;
}; 
void change1(int hh,int x,int sum,int h,int t)
{
    down(hh,x); 
    if (h>p[hh][x].t || p[hh][x].h>t) return;
    if (h<=p[hh][x].h && p[hh][x].t<=t)
    {
      p[hh][x].lazy1+=sum,down(hh,x);
        return;
  }
    change1(hh,x*2,sum,h,t);
    change1(hh,x*2+1,sum,h,t);
    p[hh][x].x1=p[hh][x*2].x1+p[hh][x*2+1].x1;
  p[hh][x].x2=max(p[hh][x*2].x2,p[hh][x*2+1].x2);
  p[hh][x].x3=min(p[hh][x*2].x3,p[hh][x*2+1].x3);
};
void change2(int hh,int x,int sum,int h,int t)
{
    down(hh,x);
    if (h>p[hh][x].t || p[hh][x].h>t) return;
    if (h<=p[hh][x].h && p[hh][x].t<=t)
    {
      p[hh][x].lazy1=0,p[hh][x].lazy2=sum,down(hh,x);
        return;
  }
    change2(hh,x*2,sum,h,t);
    change2(hh,x*2+1,sum,h,t);
    p[hh][x].x1=p[hh][x*2].x1+p[hh][x*2+1].x1;
  p[hh][x].x2=max(p[hh][x*2].x2,p[hh][x*2+1].x2);
  p[hh][x].x3=min(p[hh][x*2].x3,p[hh][x*2+1].x3);
};
re query(int hh,int x,int h,int t)
{  
  re tmp,tmp1,tmp2;
  tmp.a=0; tmp.b=0; tmp.c=1000000000;
  down(hh,x);
    if (h>p[hh][x].t || p[hh][x].h>t) return(tmp);
    if (h<=p[hh][x].h && p[hh][x].t<=t)
    {
        tmp.a=p[hh][x].x1,tmp.b=p[hh][x].x2,tmp.c=p[hh][x].x3;
        return(tmp);
  }
    tmp1=query(hh,x*2,h,t); tmp2=query(hh,x*2+1,h,t);
    tmp.a=tmp1.a+tmp2.a; tmp.b=max(tmp1.b,tmp2.b); tmp.c=min(tmp1.c,tmp2.c);
    return(tmp);
};
int main()
{
  int n,m,k,a1,a2,a3,a4,a5,a6;
  while (cin>>n>>m>>k)
  {
      memset(p,0,sizeof(p));
      for (int i=1; i<=n;i++)
        build(i,1,1,m);
      for (int i=1;i<=k;i++)
    {
        cin>>a1>>a2>>a3>>a4>>a5;
        if (a1==1)
        {
            cin>>a6;
            for (int j=a2;j<=a4;j++)
              change1(j,1,a6,a3,a5);
        }
        if (a1==2)
        {
            cin>>a6;
            for (int j=a2;j<=a4;j++)
              change2(j,1,a6,a3,a5);
        }
        if (a1==3)
        {
            int sum1=0,maxn=0,minn=1000000000; 
            for (int j=a2;j<=a4;j++)
                {
                    tmp=query(j,1,a3,a5);
                    sum1+=tmp.a;
                    maxn=max(maxn,tmp.b);
                    minn=min(minn,tmp.c);
              }
              cout<<sum1<<" "<<minn<<" "<<maxn<<endl; 
        }
    }
  }
  return(0);
}

 

posted @ 2017-12-19 22:11  尹吴潇  阅读(263)  评论(0编辑  收藏  举报