瑶瑶想要玩滑梯
Time Limit:10000/5000 MS (Java/Others)
Memory Limit:512000/256000 KB (Java/Others)
众所周知,瑶瑶(tsyao)是个贪玩的萌妹子,特别喜欢闹腾,恰好今天是一个风和日丽的日子,瑶瑶嚷着让姐姐带她去去公园玩滑梯,可是公园的滑梯比较独特,由单位积木搭成,积木是排成一排搭好,每列有xi个积木,共n列。小明能够对积木进行m次操作:
1.U L R yi : 将[L,R]列的积木高度全都改为yi
2.Q L R : 查询[L,R]列最长连续上升的列长度(LCIS)
知道[L,R]列最长连续上升的列长度过后,瑶瑶就可以开开心心地玩滑梯啦!
Ps:连续上升的列长度指对于一段合法区间,都有 。
话说积木是平的,瑶瑶是怎么从高处滑到低处的呢??作为姐姐也不知道,很想知道吧?你去问她吧。。
第一行 两个整数n,m;
第二行 n个整数,分别为[1,n]区间每列积木个数;
接下来m行为m个操作
输出x行,每行为每次操作2的查询结果。
5 4
2 1 2 3 1
Q 1 4
Q 2 5
U 2 4 3
Q 1 5
3
3
2
对于 100%的数据,有1 ≤ n ≤ 10^5 , 1 ≤ m ≤ 10^5 , 1 ≤ xi ≤ 10^8。
单组输入,共10组数据。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std ; #define lson l , m , o << 1 #define rson m + 1 , r , o << 1 | 1 const int maxT = 1000000; const int maxN = 100005; int a[ maxN ] ; int maxo[ maxT ] , maxl[ maxT ] , maxr[ maxT ] ; int numl[ maxT ] , numr[ maxT ] , mark[ maxT ] ; int max ( const int X , const int Y ) { return X > Y ? X : Y ; } int min ( const int X , const int Y ) { return X < Y ? X : Y ; } void PushUp ( int l , int r , int o ) { int m = ( l + r ) >> 1 ; maxo[ o ] = max ( maxo[ o << 1 ] , maxo[ o << 1 | 1 ] ) ; maxl[ o ] = maxl[ o << 1 ] ; maxr[ o ] = maxr[ o << 1 | 1 ] ; numl[ o ] = numl[ o << 1 ] ; numr[ o ] = numr[ o << 1 | 1 ] ; if ( numr[ o << 1 ] < numl[ o << 1 | 1 ] ) { maxo[ o ] = max ( maxo[ o ] , maxr[ o << 1 ] + maxl[ o << 1 | 1 ] ) ; if ( maxl[ o ] == m - l + 1 ) { maxl[ o ] += maxl[ o << 1 | 1 ] ; } if ( maxr[ o ] == r - m ) { maxr[ o ] += maxr[ o << 1 ] ; } } } void PushDown ( int o ) { if ( mark[ o ] ) { mark[ o << 1 ] = mark[ o << 1 | 1 ] = mark[ o ] ; numl[ o << 1 ] = numr[ o << 1 ] = mark[ o << 1 ] ; maxl[ o << 1 ] = maxr[ o << 1 ] = maxo[ o << 1 ] = 1 ; numl[ o << 1 | 1 ] = numr[ o << 1 | 1 ] = mark[ o << 1 | 1 ] ; maxl[ o << 1 | 1 ] = maxr[ o << 1 | 1 ] = maxo[ o << 1 | 1 ] = 1 ; mark[ o ] = 0 ; } } void Build ( int l , int r , int o ) { mark[ o ] = 0 ; if ( l == r ) { maxo[ o ] = maxl[ o ] = maxr[ o ] = 1 ; numl[ o ] = numr[ o ] = a[ l ] ; } else { int m = ( l + r ) >> 1 ; Build ( lson ) ; Build ( rson ) ; PushUp ( l , r , o ) ; } } void Update ( int L , int R , int c , int l , int r , int o ) { if ( L <= l && r <= R ) { maxo[ o ] = maxl[ o ] = maxr[ o ] = 1 ; numl[ o ] = numr[ o ] = mark[ o ] = c ; return ; } PushDown ( o ) ; int m = ( l + r ) >> 1 ; if ( L <= m ) Update ( L , R , c , lson ) ; if ( m < R ) Update ( L , R , c , rson ) ; PushUp ( l , r , o ) ; } int Query ( int L , int R , int l , int r , int o ) { if ( L <= l && r <= R ) return maxo[ o ] ; PushDown ( o ) ; int tmp1 = 0 , tmp2 = 0 , tmp3 = 0 , m = ( l + r ) >> 1 ; if ( L <= m ) tmp1 = Query ( L , R , lson ) ; if ( m < R ) tmp2 = Query ( L , R , rson ) ; if ( L <= m && m < R ) { if ( numr[ o << 1 ] < numl[ o << 1 | 1 ] ) { tmp3 = min ( maxr[ o << 1 ] , m - L + 1 ) + min ( maxl[ o << 1 | 1 ] , R - m ) ; } } return max ( tmp1 , max ( tmp2 , tmp3 ) ) ; } void work () { int n , m , L , R , C; char ch[ 5 ] ; scanf ( "%d%d" , &n , &m ) ; for ( int i = 1 ; i <= n ; ++ i ) { scanf ( "%d", &a[i] ) ; } Build ( 1 , n , 1 ) ; for ( int i = 0 ; i < m ; ++ i ) { scanf ( "%s" , ch ) ; if ( ch[ 0 ] == 'U' ) { scanf ( "%d%d%d" , &L , &R , &C ) ; Update ( L , R , C , 1 , n , 1 ) ; } else { scanf ( "%d%d" , &L , &R ) ; int ans = Query ( L , R , 1 , n , 1 ) ; printf ( "%d\n" , ans ) ; } } } int main () { work () ; return 0 ; }