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
1 1 4 2 3 1 2 5
区间合并,
维护一个区间的包含最左的元素的LCIS,包含最右元素的LCIS,以及整个区间的LCIS,然后更新的时候就更新这三个值就行了。
代码
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; typedef struct { int l,r,val,lval,rval; }Tree; Tree tree[3000000]; int a[500005]; void PushUp(int t) { // printf("%d %d %d %d !!!!\n",tree[2*t+1].r,tree[2*t+2].l,a[tree[2*t+1].r],a[tree[2*t+2].l]); tree[t].val=max(tree[2*t+1].val,tree[2*t+2].val); if (a[tree[2*t+1].r]>=a[tree[2*t+2].l]) { tree[t].lval=tree[2*t+1].lval; tree[t].rval=tree[2*t+2].rval; } else { tree[t].val=max(tree[t].val,tree[2*t+1].rval+tree[2*t+2].lval); if (tree[2*t+1].lval==tree[2*t+1].r-tree[2*t+1].l+1) tree[t].lval=tree[2*t+1].lval+tree[2*t+2].lval; else tree[t].lval=tree[2*t+1].lval; if (tree[2*t+2].rval==tree[2*t+2].r-tree[2*t+2].l+1) tree[t].rval=tree[2*t+1].rval+tree[2*t+2].rval; else tree[t].rval=tree[2*t+2].rval; tree[t].val=max(max(tree[t].val,tree[t].lval),tree[t].rval); } // printf("%d %d %d %d %d\n",tree[t].l,tree[t].r,tree[t].val,tree[t].lval,tree[t].rval); } void Build(int t,int l,int r) { tree[t].l=l; tree[t].r=r; if (l==r) { scanf("%d",&a[l]); tree[t].val=a[l]; tree[t].lval=tree[t].rval=tree[t].val=1; return; } int mid=(l+r)>>1; Build(2*t+1,l,mid); Build(2*t+2,mid+1,r); PushUp(t); } int Query(int t,int l,int r) { if (tree[t].l==l && tree[t].r==r) { return tree[t].val; } int mid=(tree[t].l+tree[t].r)>>1; int cnt=0; if (l<=mid) cnt=max(cnt,Query(2*t+1,l,min(r,mid))); if (r>mid) cnt=max(cnt,Query(2*t+2,max(l,mid+1),r)); if (l>mid || r<=mid || a[tree[2*t+1].r]>=a[tree[2*t+2].l]) return cnt; int tmp=min(tree[2*t+1].rval,mid-l+1)+min(tree[2*t+2].lval,r-mid); return max(tmp,cnt); } void Update(int t,int x,int val) { if (tree[t].l==tree[t].r) { a[tree[t].l]=val; return; } int mid=(tree[t].l+tree[t].r)>>1; if (x<=mid) Update(2*t+1,x,val); else Update(2*t+2,x,val); PushUp(t); } int main() { int i,j,n,T,m,x,y; char str[5]; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); Build(0,0,n-1); while(m--) { scanf("%s%d%d",str,&x,&y); if (str[0]=='Q') { printf("%d\n",Query(0,x,y)); } else { Update(0,x,y); } } } return 0; }