hdu3308

区间合并比较模板的题,就是求一个区间的LCIS

线段树维护左最大LCIS,右最大LCIS,区间LCIS

看代码就行

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 100005
int lval[maxn<<2],rval[maxn<<2];//Çø¼ä×óÓҶ˵ãÖµ
int lmx[maxn<<2],rmx[maxn<<2],mx[maxn<<2];//Çø¼ä×ó²àLCIS£¬Çø¼äÓÒ²àLCIS£¬Çø¼äLCIS
inline void pushup(int rt,int l,int r){
    lval[rt]=lval[rt<<1];rval[rt]=rval[rt<<1|1];//¸üÐÂ×óÓҶ˵ã
    //¸üÐÂ×óÓÒLCISºÍLCIS
    lmx[rt]=lmx[rt<<1];//×ó¶Ë
    rmx[rt]=rmx[rt<<1|1];//ÓÒ¶Ë
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
    
    int m=l+r>>1;
    int lenl=m-l+1,lenr=r-m;//×óÓÒ×ÓÇø¼ä³¤¶È
    if(rval[rt<<1]<lval[rt<<1|1]){//ºÏ²¢
        
        if(lmx[rt<<1]==lenl)
            lmx[rt]+=lmx[rt<<1|1];
        if(rmx[rt<<1|1]==lenr)
            rmx[rt]+=rmx[rt<<1];
        mx[rt]=max(mx[rt],rmx[rt<<1]+lmx[rt<<1|1]);
    }
    mx[rt]=max(mx[rt],max(lmx[rt],rmx[rt]));
}
void build(int l,int r,int rt){
    if(l==r){
        scanf("%d",&lval[rt]);
        rval[rt]=lval[rt];
        lmx[rt]=rmx[rt]=mx[rt]=1;
        return;
    }
    int  m=l+r>>1;
    build(lson);
    build(rson);
    pushup(rt,l,r);
}
void update(int pos,int c,int l,int r,int rt){
    if(l==r){
        lval[rt]=rval[rt]=c;
        return;
    }
    int m=l+r>>1;
    if(pos<=m) update(pos,c,lson);
    else if(pos>m) update(pos,c,rson);
    pushup(rt,l,r);
}
int query(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r){
        return mx[rt];
    }
    int m=l+r>>1;
    if(R<=m) return query(L,R,lson);//Èç¹û[L,R]ÔÚ×óÇø¼ä
    else if(L>m) return query(L,R,rson);
    else {//µ½Á½¸öÇø¼äÀï²éÕÒ
        int temp1=query(L,R,lson);
        int temp2=query(L,R,rson);
        int temp3=0;
        if(rval[rt<<1]<lval[rt<<1|1]){
            temp3+=min(m-L+1,rmx[rt<<1]);
            temp3+=min(R-m,lmx[rt<<1|1]);
        }
        /*return max(temp3,max(temp1,temp2));*///¶ÔÓÚÁ½¸ö×ÓÇø¼ä£¬Ö»ÓÐÈýÖÖÇé¿ö×÷Ϊ×îÖÕ½á¹û£¬Ò»ÊÇ×óÇø¼äµÄLCIS£¬¶þÊÇÓÒÇø¼äµÄLCIS£¬ÈýÊǺϲ¢ºóÖмäµÄÄÇÒ»¶Î
        return max(max(temp1,temp2),temp3);
    }
}

int main(){
    int T,n,q;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&q);
        build(0,n-1,1);
        
        int a,b;
        char op[2];
        while(q--){
            scanf("%s%d%d",op,&a,&b);
            if(op[0]=='Q') printf("%d\n",query(a,b,0,n-1,1));
            else update(a,b,0,n-1,1);
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/zsben991126/p/9971648.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值