zoukankan      html  css  js  c++  java
  • (简单) HDU 3308 LCIS,线段树+区间合并。

      Problem Description

      Given n integers.
      You have two operations:
      U A B: replace the Ath number by B. (index counting from 0)
      Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].

      题目大意就是给你一个数列,求区间内的最长连续子序列。以及对某一个点的值进行更改。

      线段树维护区间内的LCIS,前缀LCIS,后缀LCIS就可。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define lson L,M,po*2
    #define rson M+1,R,po*2+1
    #define lc po*2
    #define rc po*2+1
    
    using namespace std;
    
    const int maxn=10e5+10;
    
    int mBIT[maxn*4],lBIT[maxn*4],rBIT[maxn*4];
    int num[maxn];
    
    void pushUP(int po,int len,int M)
    {
        mBIT[po]=max(mBIT[lc],mBIT[rc]);
        lBIT[po]=lBIT[lc];
        rBIT[po]=rBIT[rc];
    
        if(num[M]<num[M+1])
        {
            mBIT[po]=max(mBIT[po],rBIT[lc]+lBIT[rc]);
            
            if(lBIT[lc]==len-(len/2))
                lBIT[po]+=lBIT[rc];
    
            if(rBIT[rc]==(len/2))
                rBIT[po]+=rBIT[lc];
        }
    }
    
    void build_tree(int L,int R,int po)
    {
        if(L==R)
        {
            scanf("%d",&num[L]);
            mBIT[po]=lBIT[po]=rBIT[po]=1;
    
            return;
        }
    
        int M=(L+R)/2;
    
        build_tree(lson);
        build_tree(rson);
    
        pushUP(po,R-L+1,M);
    }
    
    void update(int up,int L,int R,int po)
    {
        if(L==R&&L==up)
            return;
    
        int M=(L+R)/2;
    
        if(up<=M)
            update(up,lson);
        else
            update(up,rson);
    
        pushUP(po,R-L+1,M);
    }
    
    int query(int ql,int qr,int L,int R,int po)
    {
        if(ql<=L&&qr>=R)
            return mBIT[po];
    
        int M=(L+R)/2;
    
        if(qr<=M)
            return query(ql,qr,lson);
        if(ql>M)
            return query(ql,qr,rson);
    
        int ans=max(query(max(ql,L),M,lson),query(M+1,min(qr,R),rson));
        int temp=min(rBIT[lc],M-ql+1)+min(lBIT[rc],qr-M);
    
        if(num[M]<num[M+1])                            //这里要判断!
            return max(ans,temp);
        else
            return ans;
    }
    
    int main()
    {
        int N,M;
        int a,b;
        char c[5];
        int T;
        cin>>T;
    
        while(T--)
        {
            scanf("%d %d",&N,&M);
    
            build_tree(0,N-1,1);
    
            while(M--)
            {
                scanf("%s %d %d",c,&a,&b);
    
                if(c[0]=='Q')
                    printf("%d
    ",query(a,b,0,N-1,1));
                else
                {
                    num[a]=b;
                    update(a,0,N-1,1);
                }
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    linux 中的vim的配置文件的位置
    centos find
    multi-cursor
    ctrlsf插件
    Vim的可视模式
    Vim的tagbar插件
    Vim的tag系统
    ~/.ctag的作用与配置
    在Vim里使用gtags-cscope
    查看Vim的option变量的值
  • 原文地址:https://www.cnblogs.com/whywhy/p/4209704.html
Copyright © 2011-2022 走看看