刚开始看到题目时吓到了。。。要求上升子序列,以为是道神题,但仔细一看原来是连续上升子序列,果断变为low题了。在网上看了一些大神的代码,感觉自己的代码简洁了不少,以前学c的一些小知识点也回顾了一遍,继续奋斗!
#include <iostream>
#include<stdio.h>
#include<cstring>
#define lt(a) a<<1
#define rt(a) a<<1|1
#define md(a,b) (a+b)>>1
using namespace std;
const int MAX=1e5+1e4;
int d[MAX],T,n,m,i;
typedef struct
{
int left,right;
int mlen,llen,rlen,len;
void set_len(int a)
{
mlen=llen=rlen=a;
}
}P;
P p[4*MAX];
void push_up(int k)
{
int lt=lt(k),rt=rt(k),mm=0;
p[k].rlen=p[rt].rlen;
p[k].llen=p[lt].llen;
int mid=md(p[k].right, p[k].left);
mm= d[mid]<d[mid+1]? p[lt].rlen+ p[rt].llen:0;
p[k].mlen=max(max( p[lt].mlen, p[rt].mlen),mm);
if( p[lt].llen== p[lt].len&&d[mid]<d[mid+1])
p[k].llen+= p[rt].llen;
if( p[rt].rlen == p[rt].len&&d[mid]<d[mid+1])
p[k].rlen+= p[lt].rlen;
}
void build(int k,int l,int r)
{
p[k].left=l;
p[k].right=r;
p[k].len= r-l+1;
if(l==r)
{
p[k].set_len(1);
return;
}
int mid=md( p[k].left, p[k].right),rt=rt(k),lt=lt(k);
build(lt,l,mid);
build(rt,mid+1,r);
push_up(k);
}
void update(int k,int a,int b)
{
if( p[k].left== p[k].right )
{
d[a]=b;
return;
}
int mid=md( p[k].left, p[k].right),rt=rt(k),lt=lt(k);
if(a<=mid)
update(lt,a,b);
else
update(rt,a,b);
push_up(k);
}
int query(int k,int a,int b)
{
if( p[k].left==a && p[k].right==b)
return p[k].mlen;
int mid=md( p[k].left, p[k].right),rt=rt(k),lt=lt(k);
if( a>mid)
return query(rt,a,b);
else
if(b<=mid)
return query(lt,a,b);
else
{
int mm= d[mid]<d[mid+1]?min(p[lt].rlen,mid-a+1)+ min(p[rt].llen,b-mid):0;
return max(max(query(lt,a,mid),query(rt,mid+1,b)),mm);
}
}
int main()
{
char ch;
int a,b;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",d+i);
build(1,0,n-1);
while(m--)
{
cin>>ch;
scanf("%d%d",&a,&b);
if(ch=='U')
update(1,a,b);
else
printf("%d\n",query(1,a,b));
}
}
return 0;
}