• 【UVa】11992 Fast Matrix Operations


      1 #include<cstdio>
      2 #define INF 0x7FFFFFFF
      3 #define MAXN 1000010
      4 struct node
      5 {
      6     int cnt,son[4],kind[4];
      7     int big,small,sum,add,cover;
      8 };
      9 node tree[MAXN<<2];
     10 int size,SUM,BIG,SMALL;
     11 inline int MAX(int x,int y)
     12 {
     13     return x>y?x:y;
     14 }
     15 inline int MIN(int x,int y)
     16 {
     17     return x>y?y:x;
     18 }
     19 void Build(int x1,int x2,int y1,int y2,int rt)
     20 {
     21     tree[rt].cnt=0;
     22     tree[rt].big=tree[rt].small=tree[rt].sum=tree[rt].add=tree[rt].cover=0;
     23     if(x1!=x2||y1!=y2)
     24     {
     25         int i,mid1=(x1+x2)>>1,mid2=(y1+y2)>>1;
     26         if(x1<=mid1)
     27         {
     28             if(y1<=mid2)
     29             {
     30                 tree[rt].kind[tree[rt].cnt]=1;
     31                 tree[rt].son[tree[rt].cnt++]=size++;
     32             }
     33             if(y2>mid2)
     34             {
     35                 tree[rt].kind[tree[rt].cnt]=2;
     36                 tree[rt].son[tree[rt].cnt++]=size++;
     37             }
     38         }
     39         if(x2>mid1)
     40         {
     41             if(y1<=mid2)
     42             {
     43                 tree[rt].kind[tree[rt].cnt]=3;
     44                 tree[rt].son[tree[rt].cnt++]=size++;
     45             }
     46             if(y2>mid2)
     47             {
     48                 tree[rt].kind[tree[rt].cnt]=4;
     49                 tree[rt].son[tree[rt].cnt++]=size++;
     50             }
     51         }
     52         for(i=0;i<tree[rt].cnt;i++)
     53         {
     54             if(tree[rt].kind[i]==1)
     55                 Build(x1,mid1,y1,mid2,tree[rt].son[i]);
     56             else if(tree[rt].kind[i]==2)
     57                 Build(x1,mid1,mid2+1,y2,tree[rt].son[i]);
     58             else if(tree[rt].kind[i]==3)
     59                 Build(mid1+1,x2,y1,mid2,tree[rt].son[i]);
     60             else
     61                 Build(mid1+1,x2,mid2+1,y2,tree[rt].son[i]);
     62         }
     63     }
     64 }
     65 void PushDown(int x1,int x2,int mid1,int y1,int y2,int mid2,int rt)
     66 {
     67     int i;
     68     if(tree[rt].cover)
     69     {
     70         for(i=0;i<tree[rt].cnt;i++)
     71         {
     72             if(tree[rt].kind[i]==1)
     73                 tree[tree[rt].son[i]].sum=(mid1-x1+1)*(mid2-y1+1)*tree[rt].cover;
     74             else if(tree[rt].kind[i]==2)
     75                 tree[tree[rt].son[i]].sum=(mid1-x1+1)*(y2-mid2)*tree[rt].cover;
     76             else if(tree[rt].kind[i]==3)
     77                 tree[tree[rt].son[i]].sum=(x2-mid1)*(mid2-y1+1)*tree[rt].cover;
     78             else
     79                 tree[tree[rt].son[i]].sum=(x2-mid1)*(y2-mid2)*tree[rt].cover;
     80             tree[tree[rt].son[i]].add=0;
     81             tree[tree[rt].son[i]].cover=tree[tree[rt].son[i]].big=tree[tree[rt].son[i]].small=tree[rt].cover;
     82         }
     83         tree[rt].cover=0;
     84     }
     85     if(tree[rt].add)
     86     {
     87         for(i=0;i<tree[rt].cnt;i++)
     88         {
     89             if(tree[rt].kind[i]==1)
     90                 tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(mid2-y1+1)*tree[rt].add;
     91             else if(tree[rt].kind[i]==2)
     92                 tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(y2-mid2)*tree[rt].add;
     93             else if(tree[rt].kind[i]==3)
     94                 tree[tree[rt].son[i]].sum+=(x2-mid1)*(mid2-y1+1)*tree[rt].add;
     95             else
     96                 tree[tree[rt].son[i]].sum+=(x2-mid1)*(y2-mid2)*tree[rt].add;
     97             tree[tree[rt].son[i]].add+=tree[rt].add;
     98             tree[tree[rt].son[i]].big+=tree[rt].add;
     99             tree[tree[rt].son[i]].small+=tree[rt].add;
    100         }
    101         tree[rt].add=0;
    102     }
    103 }
    104 void PushUp(int rt)
    105 {
    106     int i;
    107     tree[rt].big=tree[rt].sum=0;
    108     tree[rt].small=INF;
    109     for(i=0;i<tree[rt].cnt;i++)
    110     {
    111         tree[rt].sum+=tree[tree[rt].son[i]].sum;
    112         tree[rt].big=MAX(tree[rt].big,tree[tree[rt].son[i]].big);
    113         tree[rt].small=MIN(tree[rt].small,tree[tree[rt].son[i]].small);
    114     }
    115 }
    116 void Add(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)
    117 {
    118     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
    119     {
    120         tree[rt].add+=val;
    121         tree[rt].big+=val;
    122         tree[rt].small+=val;
    123         tree[rt].sum+=val*(b-a+1)*(d-c+1);
    124     }
    125     else
    126     {
    127         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
    128         PushDown(a,b,mid1,c,d,mid2,rt);
    129         if(x1<=mid1)
    130         {
    131             if(y1<=mid2)
    132             {
    133                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
    134                 if(tree[rt].kind[i]==1)
    135                     Add(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);
    136             }
    137             if(y2>mid2)
    138             {
    139                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
    140                 if(tree[rt].kind[i]==2)
    141                     Add(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);
    142             }
    143         }
    144         if(x2>mid1)
    145         {
    146             if(y1<=mid2)
    147             {
    148                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
    149                 if(tree[rt].kind[i]==3)
    150                     Add(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);
    151             }
    152             if(y2>mid2)
    153             {
    154                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
    155                 if(tree[rt].kind[i]==4)
    156                     Add(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);
    157             }
    158         }
    159         PushUp(rt);
    160     }
    161 }
    162 void Cover(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)
    163 {
    164     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
    165     {
    166         tree[rt].add=0;
    167         tree[rt].cover=tree[rt].big=tree[rt].small=val;
    168         tree[rt].sum=val*(b-a+1)*(d-c+1);
    169     }
    170     else
    171     {
    172         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
    173         PushDown(a,b,mid1,c,d,mid2,rt);
    174         if(x1<=mid1)
    175         {
    176             if(y1<=mid2)
    177             {
    178                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
    179                 if(tree[rt].kind[i]==1)
    180                     Cover(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);
    181             }
    182             if(y2>mid2)
    183             {
    184                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
    185                 if(tree[rt].kind[i]==2)
    186                     Cover(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);
    187             }
    188         }
    189         if(x2>mid1)
    190         {
    191             if(y1<=mid2)
    192             {
    193                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
    194                 if(tree[rt].kind[i]==3)
    195                     Cover(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);
    196             }
    197             if(y2>mid2)
    198             {
    199                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
    200                 if(tree[rt].kind[i]==4)
    201                     Cover(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);
    202             }
    203         }
    204         PushUp(rt);
    205     }
    206 }
    207 void Query(int x1,int x2,int y1,int y2,int a,int b,int c,int d,int rt)
    208 {
    209     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
    210     {
    211         SUM+=tree[rt].sum;
    212         BIG=MAX(BIG,tree[rt].big);
    213         SMALL=MIN(SMALL,tree[rt].small);
    214     }
    215     else
    216     {
    217         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
    218         PushDown(a,b,mid1,c,d,mid2,rt);
    219         if(x1<=mid1)
    220         {
    221             if(y1<=mid2)
    222             {
    223                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
    224                 if(tree[rt].kind[i]==1)
    225                     Query(x1,x2,y1,y2,a,mid1,c,mid2,tree[rt].son[i]);
    226             }
    227             if(y2>mid2)
    228             {
    229                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
    230                 if(tree[rt].kind[i]==2)
    231                     Query(x1,x2,y1,y2,a,mid1,mid2+1,d,tree[rt].son[i]);
    232             }
    233         }
    234         if(x2>mid1)
    235         {
    236             if(y1<=mid2)
    237             {
    238                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
    239                 if(tree[rt].kind[i]==3)
    240                     Query(x1,x2,y1,y2,mid1+1,b,c,mid2,tree[rt].son[i]);
    241             }
    242             if(y2>mid2)
    243             {
    244                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
    245                 if(tree[rt].kind[i]==4)
    246                     Query(x1,x2,y1,y2,mid1+1,b,mid2+1,d,tree[rt].son[i]);
    247             }
    248         }
    249     }
    250 }
    251 int main()
    252 {
    253     int n,m,q;
    254     int x1,y1,x2,y2,val,flag;
    255     while(~scanf("%d%d%d",&n,&m,&q))
    256     {
    257         size=2;
    258         Build(1,n,1,m,1);
    259         while(q--)
    260         {
    261             scanf("%d%d%d%d%d",&flag,&x1,&y1,&x2,&y2);
    262             if(flag==1)
    263             {
    264                 scanf("%d",&val);
    265                 Add(x1,x2,y1,y2,val,1,n,1,m,1);
    266             }
    267             else if(flag==2)
    268             {
    269                 scanf("%d",&val);
    270                 Cover(x1,x2,y1,y2,val,1,n,1,m,1);
    271             }
    272             else
    273             {
    274                 SUM=BIG=0;
    275                 SMALL=INF;
    276                 Query(x1,x2,y1,y2,1,n,1,m,1);
    277                 printf("%d %d %d\n",SUM,SMALL,BIG);
    278             }
    279         }
    280     }
    281     return 0;
    282 }
    新博客:www.zhixiangli.com
  • 相关阅读:
    ubuntu上安装boost库
    boost array使用
    2017新年总结
    qt 设置等待事件
    vs下 qt源码调试
    使用记事本创建Web服务(WebService)
    司以类聚,人以群分
    附件上传
    DES 加密解密
    工作总结-js插件
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2570796.html
Copyright © 2020-2023  润新知