uva 11992 线段树

因为行数比较少(最多20),所以可以考虑每行建立一颗线段树进行操作,进而想到可以只建一颗线段树,将矩阵查询变成多次线段查询。另外需要注意的是两种lazy标记的优先级,只要有赋值操作,之前的所有操作都会被替代,所以pushdown的时候要先放下赋值的lazy标记。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 const int INF = 1000000007;
  7 const int N = 1000001;
  8 
  9 struct Node 
 10 {
 11     int l, r, maxn, minn, sum, add, v;
 12 } node[N << 2];
 13 
 14 void build( int i, int l, int r )
 15 {
 16     node[i].l = l, node[i].r = r;
 17     node[i].sum = node[i].maxn = node[i].minn = node[i].add = 0;
 18     node[i].v = -1;
 19     if ( l == r ) return ;
 20     int mid = ( l + r ) >> 1;
 21     build( i << 1, l, mid );
 22     build( i << 1 | 1, mid + 1, r );
 23 }
 24 
 25 void pushup( int i )
 26 {
 27     node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
 28     node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn );
 29     node[i].minn = min( node[i << 1].minn, node[i << 1 | 1].minn );
 30 }
 31 
 32 void pushdown( int i )
 33 {
 34     int lc = i << 1, rc = lc | 1;
 35     if ( node[i].v != -1 )
 36     {
 37         node[lc].v = node[lc].maxn = node[lc].minn = node[i].v;
 38         node[lc].sum = ( node[lc].r - node[lc].l + 1 ) * node[i].v;
 39         node[lc].add = 0;
 40         node[rc].v = node[rc].maxn = node[rc].minn = node[i].v;
 41         node[rc].sum = ( node[rc].r - node[rc].l + 1 ) * node[i].v;
 42         node[rc].add = 0;
 43         node[i].v = -1;
 44     }
 45     if ( node[i].add )
 46     {
 47         node[lc].add += node[i].add;
 48         node[lc].sum += ( node[lc].r - node[lc].l + 1 ) * node[i].add;
 49         node[rc].add += node[i].add;
 50         node[rc].sum += ( node[rc].r - node[rc].l + 1 ) * node[i].add;
 51         node[lc].maxn += node[i].add;
 52         node[lc].minn += node[i].add;
 53         node[rc].maxn += node[i].add;
 54         node[rc].minn += node[i].add;
 55         node[i].add = 0;
 56     }
 57 }
 58 
 59 void update( int i, int l, int r, int add )
 60 {
 61     if ( node[i].l == l && node[i].r == r )
 62     {
 63         node[i].maxn += add;
 64         node[i].minn += add;
 65         node[i].sum += ( node[i].r - node[i].l + 1 ) * add;
 66         node[i].add += add;
 67         return ;
 68     }
 69     pushdown(i);
 70     int mid = ( node[i].l + node[i].r ) >> 1;
 71     if ( r <= mid )
 72     {
 73         update( i << 1, l, r, add );
 74     }
 75     else if ( l > mid )
 76     {
 77         update( i << 1 | 1, l, r, add );
 78     }
 79     else
 80     {
 81         update( i << 1, l, mid, add );
 82         update( i << 1 | 1, mid + 1, r, add );
 83     }
 84     pushup(i);
 85 }
 86 
 87 void modify( int i, int l, int r, int v )
 88 {
 89     if ( node[i].l == l && node[i].r == r )
 90     {
 91         node[i].maxn = v;
 92         node[i].minn = v;
 93         node[i].sum = ( node[i].r - node[i].l + 1 ) * v;
 94         node[i].v = v;
 95         node[i].add = 0;
 96         return ;
 97     }
 98     pushdown(i);
 99     int mid = ( node[i].l + node[i].r ) >> 1;
100     if ( r <= mid )
101     {
102         modify( i << 1, l, r, v );
103     }
104     else if ( l > mid )
105     {
106         modify( i << 1 | 1, l, r, v );
107     }
108     else
109     {
110         modify( i << 1, l, mid, v );
111         modify( i << 1 | 1, mid + 1, r, v );
112     }
113     pushup(i);
114 }
115 
116 Node query( int i, int l, int r )
117 {
118     if ( node[i].l == l && node[i].r == r )
119     {
120         return node[i];
121     }
122     pushdown(i);
123     int mid = ( node[i].l + node[i].r ) >> 1;
124     if ( r <= mid )
125     {
126         return query( i << 1, l, r );
127     }
128     else if ( l > mid )
129     {
130         return query( i << 1 | 1, l, r );
131     }
132     else
133     {
134         Node nl = query( i << 1, l, mid );
135         Node nr = query( i << 1 | 1, mid + 1, r );
136         Node res;
137         res.maxn = max( nl.maxn, nr.maxn );
138         res.minn = min( nl.minn, nr.minn );
139         res.sum = nl.sum + nr.sum;
140         return res;
141     }
142 }
143 
144 int main ()
145 {
146     int row, col, m;
147     while ( scanf("%d%d%d", &row, &col, &m) != EOF )
148     {
149         build( 1, 1, row * col );
150         while ( m-- )
151         {
152             int op, x1, y1, x2, y2, num;
153             scanf("%d", &op);
154             if ( op == 1 )
155             {
156                 scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &num);
157                 for ( int j = x1; j <= x2; j++ )
158                 {
159                     update( 1, ( j - 1 ) * col + y1, ( j - 1 ) * col + y2, num );
160                 }
161             }
162             else if ( op == 2 )
163             {
164                 scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &num);
165                 for ( int j = x1; j <= x2; j++ )
166                 {
167                     modify( 1, ( j - 1 ) * col + y1, ( j - 1 ) * col + y2, num );
168                 }
169             }
170             else
171             {
172                 scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
173                 int s = 0, ma = -INF, mi = INF;
174                 for ( int j = x1; j <= x2; j++ )
175                 {
176                     Node tmp = query( 1, ( j - 1 ) * col + y1, ( j - 1 ) * col + y2 );
177                     s += tmp.sum;
178                     ma = max( ma, tmp.maxn );
179                     mi = min( mi, tmp.minn );
180                 }
181                 printf("%d %d %d\n", s, mi, ma);
182             }
183         }
184     }
185     return 0;
186 }

 

你可能感兴趣的:(uva 11992 线段树)