传送门:【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 ; }