因为行数比较少(最多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 }