UVA 11992 线段树

input

r c m      r<=20,1<=m<=20000

m行操作

1 x1 y1 x2 y2 v       add v

2 x1 y1 x2 y2 v       set v

3 x1 y1 x2 y2   查询该矩阵中的sum,max,min

output

对于每个3操作输出sum,max,min

做法:每行建一颗线段树

  1 #include <cstdio>
  2 #include <queue>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <map>
  9 #include <set>
 10 #include <ctime>
 11 #include <cmath>
 12 #define INF 0x7fffffff
 13 #define MAX 1000000
 14 
 15 using namespace std;
 16 
 17 struct node
 18 {
 19     int v,addv,setv,sum,min,max;
 20 };
 21 int r,c,m,x1,yy1,x2,yy2,v,op,suma,mina,maxa;
 22 node a[21][MAX*3];
 23 void pushdown(int &l,int &r,int &k,int&i)
 24 {
 25     if(a[i][k].setv==0&&a[i][k].addv==0) return;
 26     int m=l+((r-l)>>1),lc=k<<1,rc=k<<1|1,allv=a[i][k].setv+a[i][k].addv;
 27     if(a[i][k].setv)        //有set操作时优先将set操作pushdown
 28     {
 29         a[i][lc].addv=a[i][rc].addv=a[i][k].addv;
 30         a[i][lc].v=a[i][rc].v=a[i][lc].setv=a[i][rc].setv=a[i][k].setv;
 31         a[i][lc].min=a[i][rc].min=a[i][lc].max=a[i][rc].max=allv;
 32         a[i][lc].sum=(m-l+1)*allv;
 33         a[i][rc].sum=(r-m)*allv;
 34         a[i][k].setv=a[i][k].addv=0;
 35     }
 36     else                    //无set操作时只是add操作也要pushdown
 37     {
 38         a[i][lc].addv+=a[i][k].addv;
 39         a[i][rc].addv+=a[i][k].addv;
 40         a[i][lc].min+=a[i][k].addv;
 41         a[i][rc].min+=a[i][k].addv;
 42         a[i][lc].max+=a[i][k].addv;
 43         a[i][rc].max+=a[i][k].addv;
 44         a[i][lc].sum+=(m-l+1)*a[i][k].addv;
 45         a[i][rc].sum+=(r-m)*a[i][k].addv;
 46         a[i][k].addv=0;
 47     }
 48 //    printf("l:%d r:%d setv:%d add:%d
",l,r,a[i][k].setv,a[i][k].addv);
 49 }
 50 void reset(int &l,int &r,int &k,int&i)
 51 {
 52     int m=l+((r-l)>>1),lc=k<<1,rc=k<<1|1;
 53     a[i][k].sum=a[i][lc].sum+a[i][rc].sum+(r-l+1)*a[i][k].addv;
 54     a[i][k].min=min(a[i][lc].min,a[i][rc].min)+a[i][k].addv;
 55     a[i][k].max=max(a[i][lc].max,a[i][rc].max)+a[i][k].addv;
 56 }
 57 void setupdate(int l,int r,int k,int &i)
 58 {
 59     int lc=k<<1,rc=k<<1|1;
 60     if(yy1<=l&&yy2>=r)
 61     {
 62         a[i][k].min=a[i][k].max=a[i][k].setv=a[i][k].v=v;
 63         a[i][k].addv=0;
 64         a[i][k].sum=(r-l+1)*v;
 65     //printf("l:%d r:%d setv:%d add:%d
",l,r,a[i][k].setv,a[i][k].addv);
 66         return;
 67     }
 68     pushdown(l,r,k,i);
 69     int m=l+((r-l)>>1);
 70     if(yy1<=m) setupdate(l,m,lc,i);
 71     if(yy2>m) setupdate(m+1,r,rc,i);
 72     reset(l,r,k,i);
 73 }
 74 void addupdate(int l,int r,int k,int &i)
 75 {
 76     int lc=k<<1,rc=k<<1|1;
 77     if(yy1<=l&&yy2>=r)
 78     {
 79         a[i][k].addv+=v;
 80         a[i][k].sum+=(r-l+1)*v;
 81         a[i][k].min+=v;
 82         a[i][k].max+=v;
 83         return;
 84     }
 85     pushdown(l,r,k,i);
 86     int m=l+((r-l)>>1);
 87     if(yy1<=m) addupdate(l,m,lc,i);
 88     if(yy2>m) addupdate(m+1,r,rc,i);
 89     reset(l,r,k,i);
 90 }
 91 void query(int l,int r,int k,int& i,int add)
 92 {
 93     if(a[i][k].setv)
 94     {
 95         int allv=add+a[i][k].v+a[i][k].addv;
 96         suma+=allv*(min(r,yy2)-max(l,yy1)+1);
 97         mina=min(mina,allv);
 98         maxa=max(maxa,allv);
 99         //printf("addv:%d all:%d %d %d
",a[i][k].addv,add,mina,maxa);
100         return;
101     }
102     if(yy1<=l&&yy2>=r)
103     {
104         suma+=a[i][k].sum+(r-l+1)*add;
105         mina=min(mina,a[i][k].min+add);
106         maxa=max(maxa,a[i][k].max+add);
107         return;
108     }
109     int m=l+((r-l)>>1);
110     if(yy1<=m) query(l,m,k<<1,i,add+a[i][k].addv);
111     if(yy2>m) query(m+1,r,k<<1|1,i,add+a[i][k].addv);
112 }
113 int main()
114 {
115     freopen("/home/user/桌面/in","r",stdin);
116     while(scanf("%d%d%d",&r,&c,&m)==3)
117     {
118         for(int i=1;i<=r;i++) memset(a[i],0,sizeof(a[0][0])*3*c);
119         //memset(a,0,sizeof(a));
120         while(m--)
121         {
122             scanf("%d%d%d%d%d",&op,&x1,&yy1,&x2,&yy2);
123             if(op==2)
124             {
125                 scanf("%d",&v);
126                 for(int i=x1;i<=x2;i++) setupdate(1,c,1,i);
127                 //for(int i=1;i<3*c;i++) printf("%d:%d %d
",i,a[3][i].setv,a[3][i].addv);
128                 //puts("set");
129             }
130             else if(op==1)
131             {
132                 scanf("%d",&v);
133                 for(int i=x1;i<=x2;i++) addupdate(1,c,1,i);
134                 //for(int i=1;i<3*c;i++) printf("%d:%d %d
",i,a[3][i].setv,a[3][i].addv);
135                 //puts("add");
136             }
137             else
138             {
139                 suma=0;
140                 mina=INF;
141                 maxa=-INF-1;
142                 //printf("row:%d-%d
col:%d-%d
",x1,x2,yy1,yy2);
143                 //for(int i=1;i<=r;i++) printf("rowsum:%d
",a[i][1].sum);
144                 for(int i=x1;i<=x2;i++) query(1,c,1,i,0);
145                 printf("%d %d %d
",suma,mina,maxa);
146             }
147         }
148     }
149     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
150     return 0;
151 }
View Code
原文地址:https://www.cnblogs.com/cdyboke/p/4989587.html