思路:
线段树记录三个值,从左到右的,从右到左的,还有一个区间最长的,
值得注意的一点就是 pushup 的时候 要仔细,不要少合并了.
#include<bits/stdc++.h>
#define lson now << 1
#define rson now << 1 | 1
using namespace std;
const int N = 1e5+100;
int c[N],n,m;
int ls[N*4],rs[N*4],len[N*4];
char s[10];
void pushup(int now,int l,int r){
int mid = (l + r) >> 1;
ls[now] = ls[lson]; if (ls[now] == (mid - l) && (c[mid-1] < c[mid])) ls[now] += ls[rson];
rs[now] = rs[rson]; if (rs[now] == (r - mid) && (c[mid-1] < c[mid])) rs[now] += rs[lson];
len[now] = max(max(len[lson],len[rson]),max(ls[now],rs[now]));
if (c[mid-1] < c[mid]) len[now] = max(len[now],ls[rson]+rs[lson]);
}
void build(int now, int l, int r){
len[now] = 1;ls[now] = 1; rs[now] = 1;
if (l + 1 == r)return;
int mid = (l + r) >> 1;
build(lson,l,mid); build(rson,mid,r);
pushup(now,l,r);
}
void modify(int now, int l, int r, int b){
if (l + 1 == r) return;
int mid = (l + r) >> 1;
if (b < mid) modify(lson,l,mid,b);
if (b >= mid) modify(rson,mid,r,b);
pushup(now,l,r);
// printf("%d %d %d\n",len[now],l,r);
}
int query(int now, int l, int r, int a, int b){
int ans = 0;
if (a <= l && b >= r-1){
return len[now];
}
int mid = (l + r) >> 1;
if (a < mid) ans = max(ans,query(lson,l,mid,a,b));
if (b >= mid) ans = max(ans,query(rson,mid,r,a,b));
if (a < mid && b >= mid && c[mid-1] < c[mid]){
int dx = min(mid - a, rs[lson]);
int dy = min(b - mid + 1, ls[rson]);
ans = max(ans,dx+dy);
}
return ans;
}
int main(){
int _,x,y; scanf("%d",&_);
while(_--){
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; ++i)
scanf("%d",&c[i]);
build(1,1,n+1);
for (int i = 0; i < m; ++i){
scanf("%s%d%d",s,&x,&y); x++;
if (s[0] == 'Q'){
y++;
int ans = query(1,1,n+1,x,y);
printf("%d\n",ans);
} else{
c[x] = y;
modify(1,1,n+1,x);
}
}
}
return 0;
}