### 【UVALive】6709 Mosaic 二維線段樹



`#include <cstdio>#include <cstring>#include <algorithm>using namespace std ;typedef long long BigInt ;#define ls ( o << 1 )#define rs ( o << 1 | 1 )#define rt o , l , r#define root 1 , 1 , n#define lson ls , l , m#define rson rs , m + 1 , r#define mid ( ( l + r ) >> 1 )#define LLRR Lx , Rx , Ly , Ry#define clear( A , X ) memset ( A , X , sizeof A )const int maxN = 800 ;const int oo = 0x3f3f3f3f ;int mmax[maxN << 2][maxN << 2] ;int mmin[maxN << 2][maxN << 2] ;int minv , maxv ;int n ;int max ( const int a , const int b ) {if ( a > b ) return a ;return b ;}int min ( const int a , const int b ) {if ( a < b ) return a ;return b ;}void PushUp ( int pos , int o ) {mmax[pos][o] = max ( mmax[pos][ls] , mmax[pos][rs] ) ;mmin[pos][o] = min ( mmin[pos][ls] , mmin[pos][rs] ) ;}void SubBuild ( int ch , int pos , int o , int l , int r ) {mmax[pos][o] = -oo ;mmin[pos][o] =  oo ;if ( l == r ) {if ( !ch ) { scanf ( "%d" , &mmin[pos][o] ) ;mmax[pos][o] = mmin[pos][o] ;}else {mmin[pos][o] = min ( mmin[pos << 1][o] , mmin[pos << 1 | 1][o] ) ;mmax[pos][o] = max ( mmax[pos << 1][o] , mmax[pos << 1 | 1][o] ) ;}return ;}int m = mid ;SubBuild ( ch , pos , lson ) ;SubBuild ( ch , pos , rson ) ;PushUp ( pos , o ) ;}void Build ( int o , int l , int r ) {if ( l == r ) {SubBuild ( 0 , o , root ) ;return ;}int m = mid ;Build ( lson ) ;Build ( rson ) ;SubBuild ( 1 , o , root ) ;}void SubUpdate ( int ch , int pos , int y , int v , int o , int l , int r ) {if ( l == r ) {if ( !ch ) mmin[pos][o] = mmax[pos][o] = v ;else {mmin[pos][o] = min ( mmin[pos << 1][o] , mmin[pos << 1 | 1][o] ) ;mmax[pos][o] = max ( mmax[pos << 1][o] , mmax[pos << 1 | 1][o] ) ;}return ;}int m = mid ;if ( y <= m ) SubUpdate ( ch , pos , y , v , lson ) ;else          SubUpdate ( ch , pos , y , v , rson ) ;PushUp ( pos , o ) ;}void Update ( int x , int y , int v , int o , int l , int r ) {if ( l == r ) {SubUpdate ( 0 , o , y , v , root ) ;return ;}int m = mid ;if ( x <= m ) Update ( x , y , v , lson ) ;else       Update ( x , y , v , rson ) ;SubUpdate ( 1 , o , y , v , root ) ;}void SubQuery ( int L , int R , int pos , int o , int l , int r ) {if ( L <= l && r <= R ) {minv = min ( minv , mmin[pos][o] ) ;maxv = max ( maxv , mmax[pos][o] ) ;return ;}int m = mid ;if ( L <= m ) SubQuery ( L , R , pos , lson ) ;if ( m <  R ) SubQuery ( L , R , pos , rson ) ;}void Query ( int Lx , int Rx , int Ly , int Ry , int o , int l , int r ) {if ( Lx <= l && r <= Rx ) {SubQuery ( Ly , Ry , o , root ) ;return ;}int m = mid ;if ( Lx <=  m ) Query ( LLRR , lson ) ;if ( m  <  Rx ) Query ( LLRR , rson ) ;}void work () {int m , w , x , y ;int x1 , x2 , y1 , y2 ;scanf ( "%d" , &n ) ;Build ( root ) ;scanf ( "%d" , &m ) ;while ( m -- ) {scanf ( "%d%d%d" , &x , &y , &w ) ;w >>= 1 ;x1 = max ( 1 , x - w ) ;x2 = min ( n , x + w ) ;y1 = max ( 1 , y - w ) ;y2 = min ( n , y + w ) ;minv = oo , maxv = -oo ;Query ( x1 , x2 , y1 , y2 , root ) ;int v = ( minv + maxv ) >> 1 ;printf ( "%d\n" , v ) ;Update ( x , y , v , root ) ;}}int main () {int T , cas ;for ( scanf ( "%d" , &T ) , cas = 1 ; cas <= T ; ++ cas ) {printf ( "Case #%d:\n" , cas ) ;work () ;}return 0 ;}`