线段树维护LCIS 主要是Merge操作
#include<bits/stdc++.h>
#define Mem(a,b) memset(a,b,sizeof(a))
#define lson root<<1
#define rson root<<1|1
#define Mid int mid=(l+r)>>1
#define N 100100
using namespace std;
struct segtree {
int l,r,lcis,lenl,lenr;//左值,右值,左连续,右连续
};
segtree ans[N<<2];
int lazy[N<<2],ql,qr,val,res,resr,reslenr;
void pushdown(int root,int l,int r) {
if(lazy[root]) {
lazy[lson]=lazy[rson]=lazy[root];
ans[lson].lcis=ans[lson].lenl=ans[lson].lenr=1;
ans[lson].l=ans[lson].r=lazy[lson];
ans[rson].lcis=ans[rson].lenl=ans[rson].lenr=1;
ans[rson].l=ans[rson].r=lazy[rson];
lazy[root]=0;
}//这里还可以携程一个函数的形式
}
void Merge(int root,int l,int r) {//LICS的合并
ans[root].l=ans[lson].l;
ans[root].r=ans[rson].r;
ans[root].lcis=max(ans[lson].lcis,ans[rson].lcis);
ans[root].lenl=ans[lson].lenl;
ans[root].lenr=ans[rson].lenr;
Mid;
if(ans[lson].r<ans[rson].l) {
if(ans[lson].lenr+ans[rson].lenl>ans[root].lcis)
ans[root].lcis=ans[lson].lenr+ans[rson].lenl;
if(ans[lson].lenl==mid-l+1)
ans[root].lenl+=ans[rson].lenl;
if(ans[rson].lenr==r-mid)
ans[root].lenr+=ans[lson].lenr;
}
}
void build(int root,int l,int r) {
if(l==r) {
int x;
scanf("%d",&x);
ans[root].lcis=ans[root].lenl=ans[root].lenr=1;
ans[root].l=ans[root].r=x;
//printf("%d %d %d %d %d %d %d\n",l,r,ans[root].l,ans[root].r,ans[root].lcis,ans[root].lenl,ans[root].lenr);
return ;
}
Mid;
build(lson,l,mid);
build(rson,mid+1,r);
Merge(root,l,r);
}
void query(int root,int l,int r) {
if(l>qr||r<ql)
return ;
if(l>=ql&&r<=qr) {
if(res==0) {
res=ans[root].lcis;
resr=ans[root].r;
reslenr=ans[root].lenr;
return ;
}
res=max(ans[root].lcis,res);
if(resr<ans[root].l) {
res=max(res,reslenr+ans[root].lenl);
if(ans[root].lenr==r-l+1)
reslenr+=ans[root].lenr;
else
reslenr=ans[root].lenr;
} else {
reslenr=ans[root].lenr;
}
resr=ans[root].r;
return;
}
pushdown(root,l,r);
Mid;
query(lson,l,mid);
query(rson,mid+1,r);
Merge(root,l,r);
}
void update(int root,int l,int r) {
if(l>qr||r<ql)
return ;
if(l>=ql&&r<=qr) {
lazy[root]=val;
ans[root].l=ans[root].r=val;
ans[root].lcis=ans[root].lenl=ans[root].lenr=1;
return;
}
pushdown(root,l,r);
Mid;
update(lson,l,mid);
update(rson,mid+1,r);
Merge(root,l,r);
}
int main() {
//freopen("in.txt","r",stdin);
int n,m;
scanf("%d%d",&n,&m);
Mem(lazy,0);
build(1,1,n);
for(int i=1; i<=m; i++) {
char type;
scanf("\n%c",&type);
if(type=='Q') {
scanf("%d%d",&ql,&qr);
res=0;
query(1,1,n);
printf("%d\n",res);
} else {
scanf("%d%d%d",&ql,&qr,&val);
update(1,1,n);
}
}
}