依旧是一道线段树的区间更新,注意的地方是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); } }