<span style="font-family: Arial, Helvetica, sans-serif;">#include<iostream></span>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstdlib>
using namespace std;
struct Node
{
int l_value,r_value; //左端点,右端点值
int l_max,r_max; <span style="white-space:pre"> </span> // 左,右端点开始的最大LCIS
int l,r,max; <span style="white-space:pre"> </span> // 区间的左右端点位置 max值指该区间内最大的LCIS (可能是l_max r_max中之一)
};
Node tree[400024];
int num[100024];
int Max( int a , int b )
{
return a>b? a:b;
}
Node Update( Node a ,Node b ) //整段代码的重中之重 其他的操作都是很常见且很容易理解的 关于在于区间的合并操作。
{
Node t;
t.l=a.l,t.r=b.r;
t.l_value=a.l_value; //首先由左右孩子更新父亲的左右端点的值,也更新左右端点的位置
t.r_value=b.r_value;
if(a.r_value<b.l_value&&a.l_max==(a.r-a.l+1)) //如果左孩子的左端点开始的LCIS值是整个左孩子长度 同时左孩子右端点值小于右孩子左端点值 此时更新父亲节点的左端点开始的LCIS 长度为两个孩子的左端点和
t.l_max=a.l_max+b.l_max;
else t.l_max=a.l_max; //如果左右孩子无法连接 那么单独更新
if(a.r_value<b.l_value&&b.r_max==(b.r-b.l+1))
t.r_max=a.r_max+b.r_max;
else t.r_max=b.r_max; //右孩子操作同左孩子一样
if(a.r_value<b.l_value)
t.max=Max(Max(a.max,b.max),a.r_max+b.l_max); // 更新父亲的max值 如果可以连接 那么max值的来源有三项 否则两项
else t.max=Max(a.max,b.max);
return t;
}
void Maketree( int l , int r, int cnt )
{
tree[cnt].l = l;
tree[cnt].r = r;
tree[cnt].l_value = num[l];
tree[cnt].r_value = num[r];
if( l == r )
{
tree[cnt].l_max = tree[cnt].r_max = tree[cnt].max = 1;
return ;
}
int mid = ( l + r )>>1;
Maketree( l , mid ,cnt*2 );
Maketree( mid + 1 , r , cnt*2+1);
tree[cnt] = Update( tree[cnt*2] , tree[cnt*2+1] );
}
void Change( int place ,int value, int cnt )
{
if( place == tree[cnt].l&&tree[cnt].r == place )
{
tree[cnt].r_value = tree[cnt].l_value = value;
return ;
}
int mid = ( tree[cnt].r + tree[cnt].l )>>1;
if( place > mid ) Change( place , value , cnt*2+1 );
else Change( place ,value , cnt*2 );
tree[cnt] = Update( tree[cnt*2] , tree[cnt*2+1] );
}
Node Query( int l , int r, int cnt )
{
if( l<=tree[cnt].l&&r>=tree[cnt].r )
return tree[cnt];
int mid = (tree[cnt].l + tree[cnt].r)>>1;
if( l > mid ) return Query( l , r , cnt*2+1 );
else if( r <= mid ) return Query( l ,r ,cnt *2 );
else
{
Node a,b;
a = Query( l , mid , cnt*2 );
b = Query( mid + 1, r ,cnt*2 + 1);
return Update( a ,b );
}
}
int main( )
{
int n,N,m,A,B;
char c[4];
while( scanf( "%d",&N )==1 )
{
while( N-- )
{
scanf( "%d%d",&n,&m );
for( int i = 0; i< n ;i++ )
scanf( "%d",&num[i] );
Maketree( 0 , n-1 , 1 );
for( int i = 0 ; i< m ; i++ )
{
scanf( "%s%d%d",c , &A ,&B );
if( c[0]=='U' )
{
Change( A , B , 1 );
}
else
{
Node t = Query( A , B ,1 );
printf( "%d\n",t.max );
}
}
}
}
return 0;
}