zoukankan      html  css  js  c++  java
  • Fast Matrix Operations

    uva11992:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143

    题意:给你n*m的矩阵初始化的时候矩阵里面的元素全部是0,对于这个矩阵有3中操作。

    1 x1 y1 x2 y2 v   把(x1 y1 x2 y2)子矩阵 里面的元素全部加上v 

    2 x1 y1 x2 y2 v   把(x1 y1 x2 y2)子矩阵 里面的元素全部置成v

    3 x1 y1 x2 y2  求(x1 y1 x2 y2)子矩阵的和,以及最小值和最大值

    题解:很明显是二维线段树维护,并且题目中的n不超过20.打20棵线段树就可以解决。这里的置成v,可以看成是*0+v,加上v可以看成*1+v;

    线段树维护一个mul乘数,add加数,sum总和,minn最小值,maxn最大值。注意pushdown时候对子节点先*后加。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 const int N=100002;
      7 struct SegTree{
      8    int l,r;
      9    int add,mul;
     10    int sum,minn,maxn;
     11    void init(){
     12      add=0;mul=1;
     13    }
     14    inline int mid(){
     15         return (l+r)>> 1;
     16     }
     17     inline int len(){
     18         return r-l+1;
     19     }
     20     void to_mul(int m){//每次*一个数,那么之前add的数此时也要*这个数
     21         sum *=m;
     22         minn*=m;
     23         maxn*=m;
     24         mul *= m;
     25         add *= m;
     26     }
     27     void to_add(int a){
     28         minn+=a;
     29         maxn+=a;
     30         sum +=a* len();
     31         add +=a;
     32     }
     33 }T[23][N*4];
     34 void pushdown(int num,int rt){//这里一定要注意
     35     T[num][rt<<1].to_mul(T[num][rt].mul);
     36     T[num][rt<<1|1].to_mul(T[num][rt].mul);
     37     T[num][rt<<1].to_add(T[num][rt].add);
     38     T[num][rt<<1|1].to_add(T[num][rt].add);
     39     T[num][rt].init();
     40 }
     41 void pushup(int num,int rt){
     42    T[num][rt].sum=T[num][rt<<1].sum+T[num][rt<<1|1].sum;
     43    T[num][rt].maxn=max(T[num][rt<<1].maxn,T[num][rt<<1|1].maxn);
     44    T[num][rt].minn=min(T[num][rt<<1].minn,T[num][rt<<1|1].minn);
     45 }
     46 void build(int num,int rt,int l,int r){
     47     T[num][rt].l=l;
     48     T[num][rt].r=r;
     49     T[num][rt].minn=T[num][rt].maxn=T[num][rt].sum=0;
     50     T[num][rt].init();
     51     if(l==r){
     52     return;
     53     }
     54     int mid=T[num][rt].mid();
     55     build(num,rt<<1,l,mid);
     56     build(num,rt<<1|1,mid+1,r);
     57     pushup(num,rt);
     58 }
     59 void update(int num,int rt,int l,int r,int mul,int add){
     60        if(T[num][rt].l==l&&T[num][rt].r==r){
     61            T[num][rt].to_mul(mul);
     62            T[num][rt].to_add(add);
     63            return;
     64        }
     65       pushdown(num,rt);
     66       int mid=T[num][rt].mid();
     67       if(mid>=r)update(num,rt<<1,l,r,mul,add);
     68       else if(mid<l)update(num,rt<<1|1,l,r,mul,add);
     69       else {
     70         update(num,rt<<1,l,mid,mul,add);
     71         update(num,rt<<1|1,mid+1,r,mul,add);
     72       }
     73      pushup(num,rt);
     74 }
     75 SegTree query(int num,int rt,int l,int r){
     76         if(T[num][rt].l==l&&T[num][rt].r==r)
     77             return T[num][rt];
     78         pushdown(num,rt);
     79         int mid=T[num][rt].mid();
     80         if(mid>=r)return query(num,rt<<1,l,r);
     81         else if(mid<l)return query(num,rt<<1|1,l,r);
     82         else{
     83             SegTree  t1=query(num,rt<<1,l,mid);
     84             SegTree  t2=query(num,rt<<1|1,mid+1,r);
     85              SegTree  t;
     86              t.maxn=max(t1.maxn,t2.maxn);
     87              t.minn=min(t1.minn,t2.minn);
     88              t.sum=t1.sum+t2.sum;
     89               return t;
     90         }
     91 }
     92 int n,m,r;
     93 int x1,y1,x2,y2,val,type;
     94 int main(){
     95    while(~scanf("%d%d%d",&r,&n,&m)){
     96        for(int i=1;i<=r;i++)
     97           build(i,1,1,n);
     98        for(int i=1;i<=m;i++){
     99           scanf("%d%d%d%d%d",&type,&x1,&y1,&x2,&y2);
    100           if(type==1){
    101             scanf("%d",&val);
    102             for(int i=x1;i<=x2;i++)
    103                 update(i,1,y1,y2,1,val);
    104           }
    105           else if(type==2){
    106             scanf("%d",&val);
    107             for(int i=x1;i<=x2;i++)
    108                 update(i,1,y1,y2,0,val);
    109           }
    110           else {
    111             int sum=0,minn=1000000002,maxn=0;
    112             SegTree ans;
    113             for(int i=x1;i<=x2;i++){
    114                 ans=query(i,1,y1,y2);
    115                 sum+=ans.sum;
    116                 minn=min(minn,ans.minn);
    117                 maxn=max(maxn,ans.maxn);
    118             }
    119             printf("%d %d %d
    ",sum,minn,maxn);
    120           }
    121        }
    122    }
    123 
    124 }
    View Code
  • 相关阅读:
    [ZJOI 2012]数列
    [JSOI 2011]柠檬
    sonar错误及修改方案
    mysql 查询该字段不包含中文
    service 事务
    mysql 不等于和null
    java文件编译为class文件
    主,副时间排序
    MySQL 按首字母排序
    excle导入
  • 原文地址:https://www.cnblogs.com/chujian123/p/3840487.html
Copyright © 2011-2022 走看看