【UVALive】6709 Mosaic 二維線段樹


傳送門:【UVALive】6709 Mosaic

題目大意:
每次選擇矩陣中的一個點,求以他為中心,邊長為D(D一定是奇數)的矩陣中的最小值min和最大值max,輸出ans =(min+max)/ 2(向下取整)。然后將該點的值修改為ans。

題目分析:
赤果果的二維線段樹單點修改、區間查詢。
又一次學習了線段樹,發現原來所有的更新操作全部放在二維中即可。
很不錯,一定要經常看看,溫故知新~

代碼如下:

#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 ;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com