LCIS
题意:标号1~n的数,两种操作:U a b:下标为a的数改为b;Q a b:查询区间[a, b]中的最长连续递增子序列;
思路:对于区间[l, r] ;lmax表示以l为起点的最长连续递增子序列,rmax表示以r为终点的最长连续递增子序列,Max表示区间[l, r]中的最长连续递增子序列;
对于两个相邻的区间,如果左区间的最后一个数小于右区间的第一个数,那么左右区间就可以合并左的rmax+右的lmax;
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node{
int l, r, len, lmax, rmax, Max;
}tr[maxn<<2];
int a[maxn];
void pushup(int m){
int mid=(tr[m].l+tr[m].r)>>1;
int x=a[mid], y=a[mid+1];
if(x<y){
tr[m].lmax=tr[m<<1].lmax;
if(tr[m<<1].lmax==tr[m<<1].len) tr[m].lmax+=tr[m<<1|1].lmax;
tr[m].rmax=tr[m<<1|1].rmax;
if(tr[m<<1|1].rmax==tr[m<<1|1].len) tr[m].rmax+=tr[m<<1].rmax;
tr[m].Max=max(max(max(tr[m<<1].Max, tr[m<<1|1].Max), max(tr[m].lmax, tr[m].rmax)), tr[m<<1].rmax+tr[m<<1|1].lmax);
}
else{
tr[m].lmax=tr[m<<1].lmax;
tr[m].rmax=tr[m<<1|1].rmax;
tr[m].Max=max(tr[m<<1].Max, tr[m<<1|1].Max);
}
}
void build(int m, int l, int r){
tr[m].l=l;
tr[m].r=r;
tr[m].len=r-l+1;
if(l==r){
tr[m].lmax=tr[m].rmax=tr[m].Max=1;
return;
}
int mid=(l+r)>>1;
build(m<<1, l, mid);
build(m<<1|1, mid+1, r);
pushup(m);
}
void updata(int m, int index, int val){
if(tr[m].l==tr[m].r){
a[index]=val;
return;
}
int mid=(tr[m].l+tr[m].r)>>1;
if(index<=mid) updata(m<<1, index, val);
else updata(m<<1|1, index, val);
pushup(m);
}
int query(int m, int l, int r){
if(tr[m].l==l&&tr[m].r==r){
return tr[m].Max;
}
int mid=(tr[m].l+tr[m].r)>>1;
int temp;
if(r<=mid) temp=query(m<<1, l, r);
else if(l>mid) temp=query(m<<1|1, l, r);
else{
int x=a[mid], y=a[mid+1];
if(x<y){
node t;
t.lmax=query(m<<1, l, mid);
t.rmax=query(m<<1|1, mid+1, r);
temp=max(max(t.lmax, t.rmax), min(mid-l+1, tr[m<<1].rmax)+min(r-mid, tr[m<<1|1].lmax));
}
else{
temp=max(query(m<<1, l, mid), query(m<<1|1, mid+1, r));
}
}
return temp;
}
void print(int m){
if(tr[m].l==tr[m].r){
printf("%d ", a[tr[m].l]);
return;
}
print(m<<1);
print(m<<1|1);
}
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, 1, n);
char op[5];
int a, b;
while(m--){
scanf("%s%d%d", op, &a, &b);
a++, b++;
if(op[0]=='Q') printf("%d\n", query(1, a, b));
else updata(1, a, --b);
}
}
return 0;
}