首页 > 代码库 > Fast Matrix Operations(UVA)11992

Fast Matrix Operations(UVA)11992

UVA 11992 - Fast Matrix Operations

 

给定一个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,最大最小值max,min;

思路:线段树区间更新+lazy

每行维护一个线段树,然后,线段树维护四个值,max,min,sum,set,add。如果当前set,add都有值,那么先操作set再add,复杂度(n*log(n));

  1 #include<stdio.h>  2 #include<algorithm>  3 #include<iostream>  4 #include<string.h>  5 #include<queue>  6 #include<stack>  7 #include<math.h>  8 using namespace std;  9 typedef long long LL; 10 typedef  struct node 11 { 12         int addv; 13         int setv; 14         int maxx; 15         int minn; 16         int sum; 17         int l; 18         int r; 19         node() 20         { 21                 addv = 0; 22                 setv = 0; 23                 maxx = 0; 24                 sum = 0; 25         } 26 } tr; 27 tr tree[30][100005*8]; 28 tr flag[100005*8]; 29 void build(int l,int r,int k); 30 void update(int k,int id); 31 void add(int l,int r,int k,int nn,int mm,int id,int a); 32 void sett(int l,int r,int k,int nn,int mm,int id,int a); 33 int  asksum(int l,int r,int k,int nn,int mm,int id); 34 int askminn(int l,int r,int k,int nn,int mm,int id); 35 int askmaxx(int l,int r,int k,int nn,int mm,int id); 36 int main(void) 37 { 38         int n,m,q; 39         while(scanf("%d %d %d",&n,&m,&q)!=EOF) 40         { memset(tree,0,sizeof(tree)); 41                         memset(flag,0,sizeof(flag));build(1,m,0); 42                 while(q--) 43                 { 44                         int val ; 45                         scanf("%d",&val); 46                         if(val == 1) 47                         { 48                                 int x1,y1,x2,y2,v; 49                                 scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&v); 50                                 int i,j; 51                                 for(i = x1;i <= x2;i++) 52                                 { 53                                     add(y1,y2,0,1,m,i,v); 54                                 } 55                         } 56                         else if(val == 2) 57                         { 58                                 int x1,y1,x2,y2,v;int i,j; 59                                 scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&v); 60                                 for(i = x1;i <= x2;i++) 61                                 { 62                                     sett(y1,y2,0,1,m,i,v); 63                                 } 64                         } 65                         else 66                         { 67                                 int x1,y1,x2,y2;int i,j; 68                                 scanf("%d %d %d %d",&x1,&y1,&x2,&y2); 69                                 int su = 0;int ma = 0;int mi = 1e9; 70                                 for(i = x1;i <= x2;i++) 71                                 { 72                                     su += asksum(y1,y2,0,1,m,i); 73                                     ma = max(askmaxx(y1,y2,0,1,m,i),ma); 74                                     mi = min(mi,askminn(y1,y2,0,1,m,i)); 75                                 } 76                                 printf("%d %d %d\n",su,mi,ma); 77                         } 78                 } 79         } 80         return 0; 81 } 82 void build(int l,int r,int k) 83 { 84         if(l == r) 85         { 86                 flag[k].l = l; 87                 flag[k].r = r; 88                 return ; 89         } 90         else 91         { 92                 flag[k].l = l; 93                 flag[k].r = r; 94                 build(l,(l+r)/2,2*k+1); 95                 build((l+r)/2+1,r,2*k+2); 96         } 97 } 98 void update(int k,int id) 99 {100         while(k>0)101         {102                 k = (k-1)/2;103                 int x1 = 2*k+1;104                 int x2 = 2*k+2;105                 if(tree[id][x1].setv)106                 {       //printf("1\n");107                         int xx1 = x1;108                         tree[id][2*xx1+1].setv = tree[id][x1].setv;109                         tree[id][2*xx1+2].setv = tree[id][x1].setv;110                         tree[id][2*xx1+1].addv = tree[id][x1].addv;111                         tree[id][2*xx1+2].addv = tree[id][x1].addv;112                         tree[id][x1].maxx = tree[id][x1].setv + tree[id][x1].addv;113                         tree[id][x1].minn = tree[id][x1].setv + tree[id][x1].addv;114                         tree[id][x1].sum = tree[id][x1].maxx*(flag[x1].r-flag[x1].l+1);115                         tree[id][x1].setv = 0;116                         tree[id][x1].addv = 0;117                 }118                 else if(tree[id][x1].addv)119                 {120                         int xx1 = x1;121                         tree[id][2*xx1+1].addv += tree[id][x1].addv;122                         tree[id][2*xx1+2].addv += tree[id][x1].addv;123                         tree[id][x1].maxx = tree[id][x1].maxx + tree[id][x1].addv;124                         tree[id][x1].minn = tree[id][x1].minn + tree[id][x1].addv;125                         tree[id][x1].sum += (flag[x1].r-flag[x1].l+1)*(tree[id][x1].addv);126                         tree[id][x1].setv = 0;127                         tree[id][x1].addv = 0;128                 }129                 if(tree[id][x2].setv)130                 {131                         int xx1 = x2;132                         tree[id][2*xx1+1].setv = tree[id][x2].setv;133                         tree[id][2*xx1+2].setv = tree[id][x2].setv;134                         tree[id][2*xx1+1].addv = tree[id][x2].addv;135                         tree[id][2*xx1+2].addv = tree[id][x2].addv;136                         tree[id][x2].maxx = tree[id][x2].setv + tree[id][x2].addv;137                         tree[id][x2].minn = tree[id][x2].setv + tree[id][x2].addv;138                         tree[id][x2].sum = tree[id][x2].maxx*(flag[x2].r-flag[x2].l+1);139                         tree[id][x2].setv = 0;140                         tree[id][x2].addv = 0;141                 }142                 else if(tree[id][x2].addv)143                 {        //printf("%d\n",1);144                         int xx1 = x2;145                         tree[id][2*xx1+1].addv += tree[id][x2].addv;146                         tree[id][2*xx1+2].addv += tree[id][x2].addv;147                         tree[id][x2].maxx = tree[id][x2].maxx + tree[id][x2].addv;148                         tree[id][x2].minn = tree[id][x2].minn + tree[id][x2].addv;149                         tree[id][x2].sum += (flag[x2].r-flag[x2].l+1)*(tree[id][x2].addv);150                         tree[id][x2].setv = 0;151                         tree[id][x2].addv = 0;152                 }153                 tree[id][k].maxx = max(tree[id][x1].maxx,tree[id][x2].maxx);154                 tree[id][k].minn = min(tree[id][x1].minn,tree[id][x2].minn);155                 tree[id][k].sum = tree[id][x1].sum+tree[id][x2].sum;156         }157 }158 void add(int l,int r,int k,int nn,int mm,int id,int a)159 {160         if(l > mm||r < nn)161                 return ;162         else if(l <= nn&&r >= mm)163         {164                 tree[id][k].addv += a;165                 if(tree[id][k].setv )166                 {167                         tree[id][2*k+1].setv = tree[id][k].setv;168                         tree[id][2*k+2].setv = tree[id][k].setv;169                         tree[id][2*k+1].addv = tree[id][k].addv;170                         tree[id][2*k+2].addv = tree[id][k].addv;171                         tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);172                         tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;173                         tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;174                         tree[id][k].setv = 0;175                         tree[id][k].addv = 0;176                         // update(k,id);177                 }178                 else179                 {180                         tree[id][2*k+1].addv += tree[id][k].addv;181                         tree[id][2*k+2].addv += tree[id][k].addv;182                         //printf("%d\n",tree[id][2*k+1].addv);183                         tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;184                         tree[id][k].maxx += tree[id][k].addv;185                         tree[id][k].minn += tree[id][k].addv;186                         tree[id][k].addv = 0;187                         //printf("%d\n",tree[id][k].sum);188                 }189                 update(k,id);190         }191         else192         {193                 if(tree[id][k].setv)194                 {195                         tree[id][2*k+1].setv = tree[id][k].setv;196                         tree[id][2*k+2].setv = tree[id][k].setv;197                         tree[id][2*k+1].addv = tree[id][k].addv;198                         tree[id][2*k+2].addv = tree[id][k].addv;199                         tree[id][k].setv = 0;200                         tree[id][k].addv = 0;201                 }202                 else if(tree[id][k].addv)203                 {204                         tree[id][2*k+1].addv += tree[id][k].addv ;205                         tree[id][2*k+2].addv += tree[id][k].addv;206                         tree[id][k].addv = 0;207                 }208                 add(l,r,2*k+1,nn,(nn+mm)/2,id,a);209                 add(l,r,2*k+2,(nn+mm)/2+1,mm,id,a);210         }211 }212 void sett(int l,int r,int k,int nn,int mm,int id,int a)213 {214         if(l > mm||r < nn)215                 return ;216         else if(l <= nn&&r >= mm)217         {218                 tree[id][k].setv = a;219                 if(tree[id][k].setv != 0)220                 {221                         tree[id][k].addv = 0;222                         tree[id][2*k+1].setv = tree[id][k].setv;223                         tree[id][2*k+2].setv = tree[id][k].setv;224                         tree[id][2*k+1].addv = tree[id][k].addv;225                         tree[id][2*k+2].addv = tree[id][k].addv;226                         tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);227                         tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;228                         tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;229                         tree[id][k].setv = 0;230                         tree[id][k].addv = 0;231                 }232                 update(k,id);233         }234         else235         {236                 if(tree[id][k].setv)237                 {238                         tree[id][2*k+1].setv = tree[id][k].setv;239                         tree[id][2*k+2].setv = tree[id][k].setv;240                         tree[id][2*k+1].addv = tree[id][k].addv;241                         tree[id][2*k+2].addv = tree[id][k].addv;242                         tree[id][k].setv = 0;243                         tree[id][k].addv = 0;244                 }245                 else if(tree[id][k].addv)246                 {247                         tree[id][2*k+1].addv += tree[id][k].addv ;248                         tree[id][2*k+2].addv += tree[id][k].addv;249                         tree[id][k].addv = 0;250                 }251                 sett(l,r,2*k+1,nn,(nn+mm)/2,id,a);252                 sett(l,r,2*k+2,(nn+mm)/2+1,mm,id,a);253         }254 }255 int  asksum(int l,int r,int k,int nn,int mm,int id)256 {257         if(l>mm||r<nn)258                 return 0;259         else if(l <= nn&&r>=mm)260         {        //printf("%d %d\n",id,k);261                 if(tree[id][k].setv )262                 {263                         tree[id][2*k+1].setv = tree[id][k].setv;264                         tree[id][2*k+2].setv = tree[id][k].setv;265                         tree[id][2*k+1].addv = tree[id][k].addv;266                         tree[id][2*k+2].addv = tree[id][k].addv;267                         tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);268                         tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;269                         tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;270                         tree[id][k].setv = 0;271                         tree[id][k].addv = 0;  update(k,id);272                 }273                 else  if(tree[id][k].addv)274                 {275                         tree[id][2*k+1].addv += tree[id][k].addv;276                         tree[id][2*k+2].addv += tree[id][k].addv;277                         tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;278                         tree[id][k].maxx += tree[id][k].addv;279                         tree[id][k].minn += tree[id][k].addv;280                         tree[id][k].addv = 0;  update(k,id);281                 }282                 return tree[id][k].sum;283         }284         else285         {286                 if(tree[id][k].setv)287                 {288                         tree[id][2*k+1].setv = tree[id][k].setv;289                         tree[id][2*k+2].setv = tree[id][k].setv;290                         tree[id][2*k+1].addv = tree[id][k].addv;291                         tree[id][2*k+2].addv = tree[id][k].addv;292                         tree[id][k].setv = 0;293                         tree[id][k].addv = 0;294                 }295                 else if(tree[id][k].addv)296                 {297                         tree[id][2*k+1].addv += tree[id][k].addv ;298                         tree[id][2*k+2].addv += tree[id][k].addv;299                         tree[id][k].addv = 0;300                 }301                 int nx = asksum(l,r,2*k+1,nn,(nn+mm)/2,id);302                 int ny = asksum(l,r,2*k+2,(nn+mm)/2+1,mm,id);303                 return nx+ny;304         }305 306 }307 int askminn(int l,int r,int k,int nn,int mm,int id)308 {309         if(l>mm||r<nn)310                 return 1e9;311         else if(l <= nn&&r>=mm)312         {313                 if(tree[id][k].setv != 0)314                 {315                         tree[id][2*k+1].setv = tree[id][k].setv;316                         tree[id][2*k+2].setv = tree[id][k].setv;317                         tree[id][2*k+1].addv = tree[id][k].addv;318                         tree[id][2*k+2].addv = tree[id][k].addv;319                         tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);320                         tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;321                         tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;322                         tree[id][k].setv = 0;323                         tree[id][k].addv = 0;  update(k,id);324                 }325                 else if(tree[id][k].addv)326                 {327                         tree[id][2*k+1].addv += tree[id][k].addv;328                         tree[id][2*k+2].addv += tree[id][k].addv;329                         tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;330                         tree[id][k].maxx += tree[id][k].addv;331                         tree[id][k].minn += tree[id][k].addv;332                         tree[id][k].addv = 0;  update(k,id);333                 }334                // update(k,id);335                 return tree[id][k].minn;336         }337         else338         {339                 if(tree[id][k].setv)340                 {341                         tree[id][2*k+1].setv = tree[id][k].setv;342                         tree[id][2*k+2].setv = tree[id][k].setv;343                         tree[id][2*k+1].addv = tree[id][k].addv;344                         tree[id][2*k+2].addv = tree[id][k].addv;345                         tree[id][k].setv = 0;346                         tree[id][k].addv = 0;347                 }348                 else if(tree[id][k].addv)349                 {350                         tree[id][2*k+1].addv += tree[id][k].addv ;351                         tree[id][2*k+2].addv += tree[id][k].addv;352                         tree[id][k].addv = 0;353                 }354                 int nx = askminn(l,r,2*k+1,nn,(nn+mm)/2,id);355                 int ny = askminn(l,r,2*k+2,(nn+mm)/2+1,mm,id);356                 return min(nx,ny);357         }358 }359 int askmaxx(int l,int r,int k,int nn,int mm,int id)360 {361         if(l>mm||r<nn)362                 return 0;363         else if(l <= nn&&r>=mm)364         {365                 if(tree[id][k].setv != 0)366                 {367                         tree[id][2*k+1].setv = tree[id][k].setv;368                         tree[id][2*k+2].setv = tree[id][k].setv;369                         tree[id][2*k+1].addv = tree[id][k].addv;370                         tree[id][2*k+2].addv = tree[id][k].addv;371                         tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);372                         tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;373                         tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;374                         tree[id][k].setv = 0;375                         tree[id][k].addv = 0;  update(k,id);376                 }377                 else if(tree[id][k].addv)378                 {379                         tree[id][2*k+1].addv += tree[id][k].addv;380                         tree[id][2*k+2].addv += tree[id][k].addv;381                         tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;382                         tree[id][k].maxx += tree[id][k].addv;383                         tree[id][k].minn += tree[id][k].addv;384                         tree[id][k].addv = 0;  update(k,id);385                 }386                 //update(k,id);387                 return tree[id][k].maxx;388         }389         else390         {391                 if(tree[id][k].setv)392                 {393                         tree[id][2*k+1].setv = tree[id][k].setv;394                         tree[id][2*k+2].setv = tree[id][k].setv;395                         tree[id][2*k+1].addv = tree[id][k].addv;396                         tree[id][2*k+2].addv = tree[id][k].addv;397                         tree[id][k].setv = 0;398                         tree[id][k].addv = 0;399                 }400                 else if(tree[id][k].addv)401                 {402                         tree[id][2*k+1].addv += tree[id][k].addv ;403                         tree[id][2*k+2].addv += tree[id][k].addv;404                         tree[id][k].addv = 0;405                 }406                 int nx = askmaxx(l,r,2*k+1,nn,(nn+mm)/2,id);407                 int ny = askmaxx(l,r,2*k+2,(nn+mm)/2+1,mm,id);408                 return max(nx,ny);409         }410 }

 

 

 

Fast Matrix Operations(UVA)11992