【HDU】4902 Nice boat 线段树

传送门:【HDU】4902 Nice boat


题目分析:CLJ什么心态。。这个算中档题?。。。送分题就做出一道。。。这道也算不上中档吧ORZ。。。

其实对每个区间保存两个信息就好了。

1.num数组表示该区间是否都是一个数,一个区间的数是一个的话,num就等于这个数,否则等于-1。

2.mmax数组表示该区间的最大值,因为gcd只对该区间比x大的起作用,用这个可以剪枝?

然后还需要一个set标记,表示该区间是否应该被纯色化(变成一个数)。

然后就暴力更新就好了。。


代码如下:


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- b )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m 
#define rson rs , m + 1 , r
#define rt o , l , r
#define root 1 , 1 , n
#define mid ( ( l + r ) >> 1 )

const int MAXN = 100005 ;

int set[MAXN << 2] ;
int num[MAXN << 2] ;
int mmax[MAXN << 2] ;
int L , R , x ;

int gcd ( int a , int b ) {
	return a ? gcd ( b % a , a ) : b ;
}

void pushup ( int o ) {
	if ( num[ls] == num[rs] )
		num[o] = num[ls] ;
	else
		num[o] = -1 ;
	mmax[o] = max ( mmax[ls] , mmax[rs] ) ;
}

void pushdown ( int o ) {
	if ( ~set[o] ) {
		set[ls] = set[rs] = set[o] ;
		mmax[ls] = mmax[rs] = mmax[o] ;
		num[ls] = num[rs] = num[o] ;
		set[o] = -1 ;
	}
}

void update ( int o , int l , int r ) {
	if ( L <= l && r <= R ) {
		set[o] = num[o] = mmax[o] = x ;
		return ;
	}
	pushdown ( o ) ;
	int m = mid ;
	if ( L <= m )
		update ( lson ) ;
	if ( m <  R )
		update ( rson ) ;
	pushup ( o ) ;
}

void modify ( int o , int l , int r ) {
	if ( L <= l && r <= R && ~num[o] && num[o] > x ) {
		set[o] = num[o] = mmax[o] = gcd ( num[o] , x ) ;
		return ;
	}
	pushdown ( o ) ;
	int m = mid ;
	if ( L <= m && mmax[ls] > x )
		modify ( lson ) ;
	if ( m <  R && mmax[rs] > x )
		modify ( rson ) ;
	pushup ( o ) ;
}

void print ( int o , int l , int r ) {
	if ( l == r ) {
		printf ( "%d " , num[o] ) ;
		return ;
	}
	pushdown ( o ) ;
	int m = mid ;
	print ( lson ) ;
	print ( rson ) ;
}

void build ( int o , int l , int r ) {
	set[o] = -1 ;
	if ( l == r ) {
		scanf ( "%d" , &num[o] ) ;
		mmax[o] = num[o] ;
		return ;
	}
	int m = mid ;
	build ( lson ) ;
	build ( rson ) ;
	pushup ( o ) ;
}

void solve () {
	int n , m , ch ;
	scanf ( "%d" , &n ) ;
	build ( root ) ;
	scanf ( "%d" , &m ) ;
	while ( m -- ) {
		scanf ( "%d%d%d%d" , &ch , &L , &R , &x ) ;
		if ( ch == 1 )
			update ( root ) ;
		else
			modify ( root ) ;
	}
	print ( root ) ;
	printf ( "\n" ) ;
}
	
int main () {
	int T ;
	scanf ( "%d" , &T ) ;
	while ( T -- )
		solve () ;
	return 0 ;
}


你可能感兴趣的:(HDU)