依旧是一道线段树的区间更新,注意的地方是query时合并要处理好,有左,右,中间三种情况
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
#define MAX 100100
#define lson l,m,level*2
#define rson m+1,r,level*2+1
int a[MAX];
struct node{
int vl,vr,vm;
}tree[MAX*5];
void refresh(int l,int r,int level);
void init(int l,int r,int level);
void update(int l,int r,int level,int x,int y);
int query(int l,int r,int level,int x,int y);
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]);
}
init(1,N,1);
while(M--){
char c[2];
int x,y;
scanf("%s%d%d",c,&x,&y);
if(c[0]=='Q'){
printf("%d\n",query(1,N,1,x+1,y+1));
}
else if(c[0]=='U'){
update(1,N,1,x+1,y);
}
}
}
return 0;
}
void update(int l,int r,int level,int x,int y){
if(l==r&&x==r){
a[x] = y;
return ;
}
int m = (l+r)/2;
if(x<=m) update(lson,x,y);
else if(x>m) update(rson,x,y);
refresh(l,r,level);
}
int query(int l,int r,int level,int x,int y){
if(x<=l&&y>=r){
return tree[level].vm;
}
int m = (l+r)/2;
int sum = 0;
if(x<=m){
sum = max(query(lson,x,y),sum);
}
if(y>m){
sum = max(query(rson,x,y),sum);
}
if(a[m]<a[m+1]){
sum = max(sum,min(m-x+1,tree[level*2].vr)+min(y-m,tree[level*2+1].vl));
}
return sum;
}
void init(int l,int r,int level){
if(l==r){
tree[level].vl = tree[level].vr = tree[level].vm = 1;
return ;
}
int m = (l + r)/2;
init(lson);
init(rson);
refresh(l,r,level);
}
void refresh(int l,int r,int level){
tree[level].vl = tree[level*2].vl;
tree[level].vr = tree[level*2+1].vr;
tree[level].vm = max(tree[level*2].vm,tree[level*2+1].vm);
int m = (l+r)/2;
if(a[m]<a[m+1]){
if(tree[level*2].vl==m-l+1){
tree[level].vl += tree[level*2+1].vl;
}
if(tree[level*2+1].vr==r-m){
tree[level].vr += tree[level*2].vr;
}
tree[level].vm = max(tree[level].vm,tree[level*2+1].vl + tree[level*2].vr);
}
}