UVA 11992 ——线段树(区间修改)

解题思路:

  将矩阵每一行建立一棵线段树,进而变成一维问题求解。注意数组要开 4*N

代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 const int maxn = 1000000 + 10;
  8 
  9 const int INF = 2000000000;
 10 int q, x1_, x2_, y1, y2, v_add, v_set;
 11 
 12 struct segment_tree {
 13     int sumv[4*maxn],minv[4*maxn],maxv[4*maxn];
 14     int addv[4*maxn], setv[4*maxn];
 15     void maintain(int o, int L, int R) {
 16         int lc = 2*o, rc = 2*o + 1;
 17         sumv[o] = minv[o] = maxv[o] = 0;
 18         if(setv[o] >= 0) {
 19             sumv[o] = setv[o] * (R-L+1);
 20             minv[o] = maxv[o] = setv[o];
 21         }
 22         else if(R > L) {
 23             sumv[o] = sumv[lc] + sumv[rc];
 24             minv[o] = min(minv[lc], minv[rc]);
 25             maxv[o] = max(maxv[lc], maxv[rc]);
 26         }
 27         minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+1);
 28     }
 29     void pushdown(int o) {
 30         int lc = 2*o, rc = 2*o+1;
 31         if(setv[o] >= 0) {
 32             setv[lc] = setv[rc] = setv[o];
 33             addv[lc] = addv[rc] = 0;
 34             setv[o] = -1;
 35         }
 36         if(addv[o] > 0) {
 37             addv[lc] += addv[o];
 38             addv[rc] += addv[o];
 39             addv[o] = 0;
 40         }
 41     }
 42     void update_add(int o, int L, int R) {
 43         int lc = 2*o, rc = o*2+1;
 44         if(y1 <= L && y2 >= R) {
 45             addv[o] += v_add;
 46         }
 47         else {
 48             pushdown(o);
 49             int M = L + (R-L)/2;
 50             if(y1 <= M) update_add(lc, L, M); else maintain(lc, L, M);
 51             if(y2 > M) update_add(rc, M+1, R);else maintain(rc, M+1, R);
 52         }
 53         maintain(o, L, R);
 54     }
 55     void update_set(int o, int L, int R) {
 56         int lc = 2*o, rc = o*2+1;
 57         if(y1 <= L && y2 >= R) {
 58             setv[o] = v_set;
 59             addv[o] = 0;
 60         }
 61         else {
 62             pushdown(o);
 63             int M = L + (R-L)/2;
 64             if(y1 <= M) update_set(lc, L, M); else maintain(lc, L, M);
 65             if(y2 > M) update_set(rc, M+1, R); else maintain(rc, M+1, R);
 66         }
 67         maintain(o, L, R);
 68     }
 69 
 70     void query(int o, int L, int R, int add, int& _min, int& _max, int& _sum) {
 71         if(setv[o] >= 0) {
 72             _sum += (add+setv[o]+addv[o]) * (min(R, y2)-max(L, y1)+1);
 73             _min = min(_min, setv[o]+addv[o]+add);
 74             _max = max(_max, setv[o]+addv[o]+add);
 75         }
 76         else if(y1 <= L && y2 >= R) {
 77             _sum += sumv[o] + add * (R-L+1);
 78             _min = min(_min, minv[o]+add);
 79             _max = max(_max, maxv[o]+add);
 80         }
 81         else {
 82             int M = L + (R-L)/2;
 83             if(y1 <= M) query(o*2, L, M, add+addv[o], _min, _max, _sum);
 84             if(y2 > M) query(o*2+1, M+1, R, add+addv[o], _min, _max, _sum);
 85         }
 86     }
 87 
 88     void init() {
 89         memset(setv, -1, sizeof setv);
 90         memset(addv, 0, sizeof addv);
 91         memset(sumv, 0, sizeof sumv);
 92         memset(minv, 0, sizeof minv);
 93         memset(maxv, 0, sizeof maxv);
 94     }
 95 };
 96 int r, c, m;
 97 const int maxr = 20 + 5;
 98 
 99 segment_tree tree[maxr];
100 
101 int main(int argc, const char * argv[]) {
102     
103     while(scanf("%d%d%d", &r, &c, &m) == 3){
104         
105         for(int i = 0; i < maxr; i++) tree[i].init();
106         for(int i = 0; i < m; i++) {
107             
108             scanf("%d%d%d%d%d", &q, &x1_, &y1, &x2_, &y2);
109             if(q == 1){
110                 scanf("%d", &v_add);
111                 for(int x = x1_; x <= x2_; x++) {
112                     tree[x].update_add(1, 1, c);
113                 }
114             }
115             if(q == 2) {
116                 scanf("%d", &v_set);
117                 for(int x = x1_; x <= x2_; x++) {
118                     tree[x].update_set(1, 1, c);
119                 }
120             }
121             if(q == 3){
122                 int gmin = INF, gmax = -INF, gsum = 0;
123                 for(int x = x1_; x <= x2_; x++) {
124                     int _min = INF, _max = -INF, _sum = 0;
125                     tree[x].query(1, 1, c, 0,_min, _max, _sum);
126                     gsum += _sum;
127                     gmin = min(gmin, _min);
128                     gmax = max(gmax, _max);
129                 }
130                 printf("%d %d %d\n",  gsum, gmin, gmax);
131             }
132         }
133     }
134     return 0;
135 }

 

posted @ 2016-11-09 11:28  kiraa  阅读(242)  评论(0编辑  收藏  举报