UVa 11992 (线段树 区间修改) Fast Matrix Operations

比较综合的一道题目。

二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max

写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递标记。

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <algorithm>

  4 using namespace std;

  5 

  6 const int maxnode = 1 << 17;

  7 int _sum, _min, _max, op, x1, x2, y1, y2, x, v;

  8 

  9 struct IntervalTree

 10 {

 11     int maxv[maxnode], minv[maxnode], sumv[maxnode], setv[maxnode], addv[maxnode];

 12 

 13     void maintain(int o, int L, int R)

 14     {

 15         int lc = o*2, rc = o*2+1;

 16         if(R > L)

 17         {

 18             sumv[o] = sumv[lc] + sumv[rc];

 19             minv[o] = min(minv[lc], minv[rc]);

 20             maxv[o] = max(maxv[lc], maxv[rc]);

 21         }

 22         if(setv[o] >= 0) { maxv[o] = minv[o] = setv[o]; sumv[o] = (R-L+1)*setv[o]; }

 23         if(addv[o]) { minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += (R-L+1)*addv[o]; }

 24     }

 25 

 26     void pushdown(int o)

 27     {

 28         int lc = o*2, rc = o*2+1;

 29         if(setv[o] >= 0)

 30         {

 31             setv[lc] = setv[rc] = setv[o];

 32             addv[lc] = addv[rc] = 0;

 33             setv[o] = -1;

 34         }

 35         if(addv[o])

 36         {

 37             addv[lc] += addv[o];

 38             addv[rc] += addv[o];

 39             addv[o] = 0;

 40         }

 41     }

 42 

 43     void update(int o, int L, int R)

 44     {

 45         int lc = o*2, rc = o*2+1;

 46         if(y1 <= L && R <= y2)

 47         {

 48             if(op == 1) addv[o] += v;

 49             else { setv[o] = v; addv[o] = 0; }

 50         }

 51         else

 52         {

 53             pushdown(o);    //往下传递标记

 54             int M = (L + R) / 2;

 55             if(y1 <= M) update(lc, L, M); else maintain(lc, L, M);

 56             if(y2 > M) update(rc, M+1, R); else maintain(rc, M+1, R);

 57         }

 58         maintain(o, L, R);

 59     }

 60 

 61     void query(int o, int L, int R, int add)

 62     {

 63         if(setv[o] >= 0)

 64         {

 65             int v = setv[o] + addv[o] + add;

 66             _sum += v * (min(y2, R) - max(y1, L) + 1);

 67             _min = min(_min, v);

 68             _max = max(_max, v);

 69         }

 70         else if(y1 <= L && R <= y2)

 71         {

 72             _sum += sumv[o] + add*(R-L+1);

 73             _min = min(_min, minv[o] + add);

 74             _max = max(_max, maxv[o] + add);

 75         }

 76         else

 77         {

 78             int M = (L + R) / 2;

 79             if(y1 <= M) query(o*2, L, M, add + addv[o]);

 80             if(y2 > M) query(o*2+1, M+1, R, add + addv[o]);

 81         }

 82     }

 83 };

 84 

 85 const int maxr = 20 + 5;

 86 const int INF = 1000000000;

 87 

 88 IntervalTree tree[maxr];

 89 

 90 int main()

 91 {

 92     //freopen("in.txt", "r", stdin);

 93 

 94     int r, c, m;

 95     while(scanf("%d%d%d", &r, &c, &m) == 3)

 96     {

 97         memset(tree, 0, sizeof(tree));

 98         for(int x = 1; x <= r; x++)

 99         {

100             memset(tree[x].setv, -1, sizeof(tree[x].setv));

101             tree[x].setv[1] = 0;

102         }

103 

104         while(m--)

105         {

106             scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);

107             if(op < 3)

108             {

109                 scanf("%d", &v);

110                 for(x = x1; x <= x2; x++) tree[x].update(1, 1, c);

111             }

112             else

113             {

114                 _sum = 0; _max = -INF; _min = INF;

115                 for(x = x1; x <= x2; x++) tree[x].query(1, 1, c, 0);

116                 printf("%d %d %d\n", _sum, _min, _max);

117             }

118         }

119     }

120 

121     return 0;

122 }
代码君

 

你可能感兴趣的:(Matrix)