ACdream 1101 线段树维护LCIS

线段树维护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);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值