UVA 11992-Fast Matrix Operations(線分ツリー+区間修正+好題)

14225 ワード


 
UVA 11992-Fast Matrix Operations(線分ツリー+区間修正+好題)
 
これは白い本の上の例題で、ずっと置いていてAに落ちていないで、これは1本の線分の木の区間の修正の良い問題です.
セグメントツリーでは、3つのドメイン、max、min、sum、すなわち区間最大値、最小値、区間と
 
テーマ:
 
r   c     0  ,      

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) max,sum,min



     0< c <=20  1< m <= 20000

 
 
分析:
        r   20,                  ,

              。

       3  x1 y1 x2 y2    ,

  x1 - x2      query(),

  sum  ,max min        。



               ,   add,   set

           setv   addv。

         。

      ,set          ,    set    ,  add      ,          ,      。



1:        ,   set,   add

2:set    addv  ,  add     setv  



    

 
/* ***********************************************

ID      : whiteblock63

LANG    : G++

PROG    : Uva11992-Fast Matrix Operation

DATE    : 2014-10-05 10:34:04

************************************************ */



#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>

using namespace std;



#define CLR( a, b )        memset( a, b, sizeof(a) )

#define ls o << 1

#define rs o << 1 | 1

#define rt l, r, o

#define lson l, m, o << 1

#define rson m + 1, r, o << 1 | 1

const int NODE_SIZE = 1 << 17;

const int INF  = 0x3f3f3f3f;

int op, x1, x2, y1, y2, x, v;


// inline
void scan( int & x ){ char c; while( c = getchar(), c < '0' || c > '9' ); x = c - '0'; while( c = getchar(), c >= '0' && c <= '9' ) x = x*10 + c - '0'; }
//
struct SegTree{ int sumv[NODE_SIZE], minv[NODE_SIZE], maxv[NODE_SIZE]; int setv[NODE_SIZE], addv[NODE_SIZE]; void pushup( int l, int r, int o ){ if( l < r ){ sumv[o] = sumv[ls] + sumv[rs]; minv[o] = min( minv[ls], minv[rs] ); maxv[o] = max( maxv[ls], maxv[rs] ); } if( setv[o] >= 0 ){ minv[o] = maxv[o] = setv[o]; sumv[o] = setv[o] * ( r - l + 1 ); } if( addv[o] ){ minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * ( r - l + 1 ); } } void pushdown( int o ){ if( setv[o] >= 0 ){ setv[ls] = setv[rs] = setv[o]; addv[ls] = addv[rs] = 0; setv[o] = -1;  // } if( addv[o] ){ addv[ls] += addv[o]; addv[rs] += addv[o]; addv[o] = 0;   // } } void update( int l, int r, int o ){ if( y1 <= l && r <= y2 ){ if( op == 1 ) addv[o] += v; else setv[o] = v, addv[o] = 0; }else{ pushdown( o ); int m = l + r >> 1; if( y1 <= m ) update( lson ); else pushup( lson ); if( y2 > m ) update( rson ); else pushup( rson ); } pushup( rt ); } void query( int l, int r, int o, int& ssum, int& smin, int& smax ){ pushup( rt );  // pushdown if( y1 <= l && r <= y2 ){ ssum = sumv[o]; smin = minv[o]; smax = maxv[o]; }else{ pushdown( o ); int m = l + r >> 1; int lsum = 0, lmin = INF, lmax = -INF; int rsum = 0, rmin = INF, rmax = -INF; if( y1 <= m ) query( lson, lsum, lmin, lmax ); else pushup( lson ); if( y2 > m ) query( rson, rsum, rmin, rmax ); else pushup( rson ); ssum = lsum + rsum; smin = min( lmin, rmin ); smax = max( lmax, rmax ); } } }; const int MAXR = 20 + 5; SegTree tree[MAXR]; int main() { int r, c, m; while( ~scanf( "%d %d %d", &r, &c, &m ) ){ CLR( tree, 0 ); for( x = 1; x <= r; ++x ){ CLR( tree[x].setv, -1 ); tree[x].setv[1] = 0; } while( m-- ){ scan( op ); scan( x1 ); scan( y1 ); scan( x2 ); scan( y2 ); if( op < 3 ){ scan( v ); for( x = x1; x <= x2; ++x ) tree[x].update( 1, c, 1 ); }else{ int gsum = 0, gmin = INF, gmax = -INF; for( x = x1; x <= x2; ++x ){ int ssum, smin, smax; tree[x].query( 1, c, 1, ssum, smin, smax ); gsum += ssum; gmin = min( gmin, smin ); gmax = max( gmax, smax ); } printf("%d %d %d
", gsum, gmin, gmax ); } } } return 0; }