呵呵,原来不是最长公共上升子序列,原来是最长连续子串==
有明显的修改和查询操作,果断线段树。
对于每个节点,要存他的左右下标,和左边的数,右边的数,左边的LCIS,右边的LCIS,和总的LCIS;
关键在于向上更新。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 100010
inline int input()//比scanf快多了==
{
int ret=0;
char c;
c=getchar();
while(c<'0'||c>'9')
{
if(c=='Q') return -1;
if(c=='U') return -2;
c=getchar();
}
while(c>='0'&&c<='9')
{
ret=ret*10+c-'0';
c=getchar();
}
return ret;
}
struct node
{
int l,r;
int lsum,rsum,lnum,rnum,sum;
}root[N*6];
int tCase,n,m,a[N],x,y;
int op;
void update(int t)
{
int lenl=root[t*2].r-root[t*2].l+1;
int lenr=root[t*2+1].r-root[t*2+1].l+1;
root[t].lnum=root[t*2].lnum;
root[t].rnum=root[t*2+1].rnum;
root[t].lsum=root[t*2].lsum;
if(root[t*2].lsum==lenl&&root[t*2].rnum<root[t*2+1].lnum)
{
root[t].lsum+=root[t*2+1].lsum;
}
root[t].rsum=root[t*2+1].rsum;
if(root[t*2+1].rsum==lenr&&root[t*2].rnum<root[t*2+1].lnum)
{
root[t].rsum+=root[t*2].rsum;
}
int p=max(root[t*2].sum,root[t*2+1].sum);
if(root[t*2].rnum<root[t*2+1].lnum)
{
p=max(p,root[t*2].rsum+root[t*2+1].lsum);
}
root[t].sum=p;
}
void build(int t,int l,int r)
{
root[t].l=l;
root[t].r=r;
if(l==r)
{
root[t].lsum=root[t].rsum=root[t].sum=1;
root[t].lnum=root[t].rnum=a[l];
return;
}
int m=(l+r)>>1;
build(t*2,l,m);
build(t*2+1,m+1,r);
update(t);
}
void Add(int t,int x,int v)
{
int l=root[t].l,r=root[t].r;
int m=(l+r)>>1;
if(x==l&&r==x)
{
root[t].rnum=v;
root[t].lnum=v;
return;
}
if(x<=m) Add(t*2,x,v);
else Add(t*2+1,x,v);
update(t);
}
int query(int t,int x,int y)
{
int l=root[t].l,r=root[t].r;
int m=(l+r)>>1;
if(x==l&&r==y)
{
return root[t].sum;
}
if(y<=m)
{
return query(t*2,x,y);
}
else if(x>m)
{
return query(t*2+1,x,y);
}
else
{
int p=max(query(t*2,x,m),query(t*2+1,m+1,y));
if(root[t*2].rnum<root[t*2+1].lnum)
{
int p1=min(root[t*2].rsum,root[t*2].r-x+1);
int p2=min(root[t*2+1].lsum,y-root[t*2+1].l+1);
p=max(p,p1+p2);
}
return p;
}
}
int main()
{
tCase=input();
for(int i=1;i<=tCase;i++)
{
n=input();
m=input();
for(int j=1;j<=n;j++)
{
a[j]=input();
}
build(1,1,n);
for(int j=1;j<=m;j++)
{
op=input();
x=input();
y=input();
if(op==-2)
{
x++;
Add(1,x,y);
}
else if(op==-1)
{
x++,y++;
printf("%d\n",query(1,x,y));
}
}
}
return 0;
}