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
原文地址:https://www.cnblogs.com/chujian123/p/3840487.html