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].
Input
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
OR
Q A B(0<=A<=B< n).
Output
For each Q, output the answer.
Sample Input
1 10 10 7 7 3 3 5 9 9 8 1 8 Q 6 6 U 3 4 Q 0 1 Q 0 5 Q 4 7 Q 3 5 Q 0 2 Q 4 6 U 6 10 Q 0 9
Sample Output
1 1 4 2 3 1 2 5
题意:给你n个数,有m个操作:
U A B: 把第A个数换成B
Q A B: 求区间[A,B]中最长上升子序列
思路:求区间最长连续的1的变形,我们在合并两个区间时,左区间的右端点小于右区间的左端点时才合并。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
int a[maxn];
struct node{
int l,r;
int left,right,now;
}tree[maxn*4];
void pushup(int cur)
{
tree[cur].now=max(tree[cur<<1].now,tree[cur<<1|1].now);
tree[cur].left=tree[cur<<1].left;
if(tree[cur<<1].left==tree[cur<<1].r-tree[cur<<1].l+1&&a[tree[cur<<1].r]<a[tree[cur<<1].r+1]) tree[cur].left+=tree[cur<<1|1].left;
tree[cur].right=tree[cur<<1|1].right;
if(tree[cur<<1|1].right==tree[cur<<1|1].r-tree[cur<<1|1].l+1&&a[tree[cur<<1].r]<a[tree[cur<<1].r+1]) tree[cur].right+=tree[cur<<1].right;
if(a[tree[cur<<1].r]<a[tree[cur<<1].r+1]) tree[cur].now=max(tree[cur].now,tree[cur<<1].right+tree[cur<<1|1].left);
}
void build(int l,int r,int cur)
{
tree[cur].l=l;
tree[cur].r=r;
if(l==r)
{
tree[cur].left=tree[cur].right=tree[cur].now=1;
return ;
}
int m=(l+r)>>1;
build(l,m,cur<<1);
build(m+1,r,cur<<1|1);
pushup(cur);
}
void update(int tar,int val,int cur)
{
if(tree[cur].l==tree[cur].r)
{
a[tree[cur].l]=val;
return ;
}
if(tar<=tree[cur<<1].r) update(tar,val,cur<<1);
else update(tar,val,cur<<1|1);
pushup(cur);
}
int query(int L,int R,int cur)
{
if(L<=tree[cur].l&&tree[cur].r<=R) return tree[cur].now;
if(R<=tree[cur<<1].r) return query(L,R,cur<<1);
if(L>tree[cur<<1].r) return query(L,R,cur<<1|1);
int res=max(query(L,R,cur<<1),query(L,R,cur<<1|1));
int ll=min(tree[cur<<1].r-L+1,tree[cur<<1].right);
int rr=min(R-tree[cur<<1].r,tree[cur<<1|1].left);
if(a[tree[cur<<1].r]<a[tree[cur<<1].r+1]) res=max(res,ll+rr);
return res;
}
int main()
{
int t,n,m,x,y;
char s[2];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
build(0,n-1,1);
while(m--)
{
scanf("%s%d%d",s,&x,&y);
if(s[0]=='U') update(x,y,1);
else
{
int ans=query(x,y,1);
printf("%d\n",ans);
}
}
}
return 0;
}