题意:
Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
分析:
比较裸的线段树区间合并,做过训练指南上那道动态最大连续和(Ray,Pass me the Dishes LA3938),按照那道题的思路试着写了一下,结果很容易A掉了。另外,第一次发现scanf(“%c”,&c)会读取回车。代码可能有点丑,但是今天累了明天再总结这道题
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=100000+100;
struct node{
int l,r;
}maxv[4*maxn];
int T,n,m;
int a[maxn],maxl[4*maxn],maxr[4*maxn];
node better(node a,node b){
if((a.r-a.l)>=(b.r-b.l))
return a;
else
return b;
}
void build(int o,int L,int R){
int M=L+(R-L)/2;
if(L==R){
maxv[o].l=maxv[o].r=maxl[o]=maxr[o]=L;
return ;
}
build(2*o,L,M);
build(2*o+1,M+1,R);
if(maxr[2*o+1]==M+1&&a[M+1]>a[M])
maxr[o]=maxr[2*o];
else
maxr[o]=maxr[2*o+1];
if(maxl[2*o]==M&&a[M]<a[M+1])
maxl[o]=maxl[2*o+1];
else
maxl[o]=maxl[2*o];
maxv[o]=better(maxv[2*o],maxv[2*o+1]);
if(a[M]<a[M+1])
maxv[o]=better(maxv[o],(node){maxr[2*o],maxl[2*o+1]});
}
int p,v;//a[p]=v;
void update(int o,int L,int R){
int M=L+(R-L)/2;
if(L==R){
a[p]=v;
return ;
}
if(p<=M)update(2*o,L,M);
if(p>M)update(2*o+1,M+1,R);
if(maxr[2*o+1]==M+1&&a[M+1]>a[M])
maxr[o]=maxr[2*o];
else
maxr[o]=maxr[2*o+1];
if(maxl[2*o]==M&&a[M+1]>a[M])
maxl[o]=maxl[2*o+1];
else
maxl[o]=maxl[2*o];
maxv[o]=better(maxv[2*o],maxv[2*o+1]);
if(a[M]<a[M+1])
maxv[o]=better(maxv[o],(node){maxr[2*o],maxl[2*o+1]});
}
int ql,qr;
node query(int o,int L,int R){
node ans;
if(ql<=L&&qr>=R){
ans=maxv[o];
return ans;
}
int M=L+(R-L)/2;
if(ql>M)return query(2*o+1,M+1,R);
if(qr<=M)return query(2*o,L,M);
ans=better(query(2*o,L,M),query(2*o+1,M+1,R));
if(a[M]<a[M+1]){
int l=max(ql,maxr[2*o]);
int r=min(qr,maxl[2*o+1]);
ans=better(ans,(node){l,r});
}
return ans;
}
void tra(int o,int L,int R){
cout<<L<<"->"<<R<<" "<<maxv[o].l<<" "<<maxv[o].r<<endl;
if(L==R)
return ;
int M=L+(R-L)/2;
tra(2*o,L,M);
tra(2*o+1,M+1,R);
}
int main(){
scanf("%d",&T);
for(int k=1;k<=T;k++){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
//tra(1,1,n);
char c;
for(int i=1;i<=m;i++){
scanf(" %c",&c);
if(c=='U'){
scanf("%d%d",&p,&v);
p++;
update(1,1,n);
//tra(1,1,n);
}
if(c=='Q'){
scanf("%d%d",&ql,&qr);
ql++;qr++;
node ans=query(1,1,n);
cout<<ans.r-ans.l+1<<endl;
}
}
}
return 0;
}