跟POJ3667hotel差不多,三个数组分别记录左右和总区间,维护时注意左右,重点是query函数,没啥想法,这里参考了下别人的代码。单独拉出query函数吧
主要是如何处理横跨左右区间的查询
int query(int L,int R,int l,int r,int rt)
{
int m=(l+r)>>1;
if(L<=l&&r<=R)return msum[rt];
int ans=0;
if(R<=m)ans=max(ans,query(L,R,lson));
else if(L>m)ans=max(ans,query(L,R,rson));
else
{
ans=max(ans,query(L,R,lson));
ans=max(ans,query(L,R,rson));
int left;
int right;
if(m-L+1>=rsum[rt<<1])left=rsum[rt<<1];//左边
else left=m-L+1;
if(R-m>=lsum[rt<<1|1])right=lsum[rt<<1|1];//右边
else right=R-m;
ans=max(ans,left);
ans=max(ans,right);
if(a[m]<a[m+1])
ans=max(ans,left+right);
}
return ans;
}
完整代码:
#include <cstdio>
#include <algorithm>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define N 100005
int a[N];
int lsum[N<<2];
int rsum[N<<2];
int msum[N<<2];
void pushup(int l,int r,int rt)
{
int m=(l+r)>>1;
lsum[rt]=lsum[rt<<1];
rsum[rt]=rsum[rt<<1|1];
if(lsum[rt]==m-l+1&&a[m]<a[m+1])lsum[rt]+=lsum[rt<<1|1];
if(rsum[rt]==r-m&&a[m]<a[m+1])rsum[rt]+=rsum[rt<<1];
msum[rt]=max(msum[rt<<1],msum[rt<<1|1]);
if(a[m]<a[m+1])msum[rt]=max(msum[rt],rsum[rt<<1]+lsum[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
lsum[rt]=rsum[rt]=msum[rt]=1;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(l,r,rt);
}
void update(int k,int l,int r,int rt)
{
if(l==r)return ;
int m=(l+r)>>1;
if(k<=m)update(k,lson);
if(k>m)update(k,rson);
pushup(l,r,rt);
}
int query(int L,int R,int l,int r,int rt)
{
int m=(l+r)>>1;
if(L<=l&&r<=R)return msum[rt];
int ans=0;
if(R<=m)ans=max(ans,query(L,R,lson));
else if(L>m)ans=max(ans,query(L,R,rson));
else
{
ans=max(ans,query(L,R,lson));
ans=max(ans,query(L,R,rson));
int left;
int right;
if(m-L+1>=rsum[rt<<1])left=rsum[rt<<1];
else left=m-L+1;
if(R-m>=lsum[rt<<1|1])right=lsum[rt<<1|1];
else right=R-m;
ans=max(ans,left);
ans=max(ans,right);
if(a[m]<a[m+1])
ans=max(ans,left+right);
}
return ans;
}
int main()
{
int t,n,m,i,x,y;
char b[3];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
while(m--)
{
scanf("%s",b);
scanf("%d%d",&x,&y);
if(b[0]=='U')
{
a[x+1]=y;
update(x+1,1,n,1);
}
else
{
printf("%d\n",query(x+1,y+1,1,n,1));
}
}
}
}