很明显是区间合并的题,只需要维护左最大,最大,和右最大即可,在合并时需要讨论.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 100007
using namespace std;
int t,n,m,u,v,a[MAX];
char s[5];
struct Tree
{
int l,r,left_mx , mx , right_mx;
}tree[MAX<<2];
void push_up ( int u )
{
tree[u].left_mx = tree[u<<1].left_mx;
tree[u].right_mx = tree[u<<1|1].right_mx;
tree[u].mx = max ( tree[u<<1].mx , tree[u<<1|1].mx );
if ( a[tree[u<<1].r] >= a[tree[u<<1|1].l] ) return;
if ( tree[u<<1].left_mx == tree[u<<1].r - tree[u<<1].l + 1 )
tree[u].left_mx = tree[u<<1].left_mx + tree[u<<1|1].left_mx;
if ( tree[u<<1|1].right_mx == tree[u<<1|1].r - tree[u<<1|1].l + 1 )
tree[u].right_mx = tree[u<<1].right_mx + tree[u<<1|1].right_mx;
tree[u].mx = max ( tree[u].mx , tree[u<<1].right_mx + tree[u<<1|1].left_mx );
}
void set ( int u )
{
tree[u].left_mx = tree[u].right_mx
= tree[u].mx = 1;
}
void build ( int u , int l , int r )
{
tree[u].l = l , tree[u].r = r;
if ( l == r )
{
set ( u );
return;
}
int mid = l + r >> 1;
build ( u<<1 , l , mid );
build ( u<<1|1 , mid+1 , r );
push_up ( u );
}
void update ( int u , int x , int v )
{
int l = tree[u].l , r = tree[u].r;
if ( l == r )
{
a[x] = v;
return;
}
int mid = l + r >> 1;
if ( x > mid ) update ( u<<1|1 , x , v );
else update ( u<<1 , x , v );
push_up ( u );
}
struct Ret
{
int l,r,mx,l_mx,r_mx;
Ret ( int a , int b , int c , int d , int e )
:l(a),r(b),mx(c),l_mx(d),r_mx(e){}
Ret ( ) { }
};
Ret query ( int u , int left , int right )
{
int l = tree[u].l , r = tree[u].r;
if ( left <= l && r <= right )
return Ret ( tree[u].l , tree[u].r , tree[u].mx,
tree[u].left_mx , tree[u].right_mx );
int mid = l + r >> 1;
Ret ret1 , ret2 , ret;
int flag = 0;
if ( left <= mid && right >= l )
ret1 = query( u<<1 , left , right ),flag++;
if ( left <= r && right > mid )
ret2 = query ( u<<1|1 , left , right ),flag += 2;
if ( flag == 1 ) return ret1;
else if ( flag == 2 ) return ret2;
else
{
ret.l = ret1.l , ret.r = ret2.r;
ret.mx = max ( ret1.mx , ret2.mx );
ret.l_mx = ret1.l_mx;
ret.r_mx = ret2.r_mx;
if ( a[ret1.r] >= a[ret2.l] )
return ret;
if ( ret1.l_mx == ret1.r - ret1.l + 1 )
ret.l_mx = ret1.l_mx + ret2.l_mx;
if ( ret2.r_mx == ret2.r - ret2.l + 1 )
ret.r_mx = ret1.r_mx + ret2.r_mx;
ret.mx = max ( ret.mx , ret1.r_mx + ret2.l_mx );
return ret;
}
}
int main ( )
{
scanf ( "%d" , &t );
while ( t-- )
{
scanf ( "%d%d" , &n , &m );
for ( int i = 1 ; i <= n ; i++ )
scanf ( "%d" , &a[i] );
build ( 1 , 1 , n );
for ( int i = 0 ; i < m ; i++ )
{
scanf ( "%s" , s );
scanf ( "%d%d" , &u , &v );
u++;
if ( s[0] == 'U' )
{
update ( 1 , u , v );
/*for ( int i = 1 ; i <= n ; i++ )
printf ( "%d " , a[i] );
puts ( "" );*/
}
else
{
v++;
printf ( "%d\n" , query ( 1 , u , v ).mx );
}
}
}
}