http://acm.hdu.edu.cn/showproblem.php?pid=3308
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
struct node{
int ls,rs,ms; //ls 区间左连续序列的长度
};
node no[8*100000];
int a[8*100000];
void pushup(int cr,int l,int r){
no[cr].ls=no[cr<<1].ls;
no[cr].rs=no[cr<<1|1].rs;
no[cr].ms=max(no[cr<<1|1].ms,no[cr<<1].ms);;
int mid=(l+r)/2;
if( no[cr].ls==mid-l+1 && a[mid]<a[mid+1] ){ //区间左连续与 右子区间左连续
no[cr].ls+=no[cr<<1|1].ls;
}
if( no[cr].rs==r-mid && a[mid]<a[mid+1] ){ //区间右连续与 左子区间右连续
no[cr].rs+=no[cr<<1].rs;
}
if(a[mid]<a[mid+1])
no[cr].ms=max(no[cr].ms,no[cr<<1].rs+no[cr<<1|1].ls);
}
void build(int l,int r,int cr){
if(l==r){
no[cr].ls=no[cr].rs=no[cr].ms=1;
return ;
}
int mid=(l+r)/2;
build(l,mid,cr<<1);
build(mid+1,r,cr<<1|1);
pushup(cr,l,r);
}
int query(int l,int r,int cr,int L,int R){
if(l==L&&r==R){
return no[cr].ms;
}
int mid=(L+R)/2,ans=0;
if( r<=mid ){ //左边找
ans=query(l,r,cr<<1,L,mid);
}
else if(l>mid){ //或右边找
ans=query(l,r,cr<<1|1,mid+1,R);
}
else { //中间找
ans=max(query(l,mid,cr<<1,L,mid),query(mid+1,r,cr<<1|1,mid+1,R)); //左边最长,右边最长
if(a[mid]<a[mid+1])
ans=max( min( no[cr<<1].rs, mid-l+1 )+min( no[cr<<1|1].ls,r-mid),ans); //中间最长
}
return ans;
}
void update(int p,int val,int L,int R,int cr){
if(L==p&&R==p){
a[p]=val;
return ;
}
int mid=(L+R)/2;
if(p<=mid) update(p,val,L,mid,cr<<1);
else update(p,val,mid+1,R,cr<<1|1);
pushup(cr,L,R);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
getchar();
while(m--){
char s[5];
scanf("%s",s);
if(s[0]=='U'){
int b,c;
scanf("%d%d",&b,&c);
update(b+1,c,1,n,1);
}else {
int b,c;
scanf("%d%d",&b,&c);
b++,c++;
printf("%d\n",query(b,c,1,1,n));
}
}
}
}