HDOJ 3308 LCIS

来源:互联网 发布:mac os x系统 编辑:程序博客网 时间:2024/05/17 04:01

跟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 100005int 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));            }        }    }}


原创粉丝点击