• hdu 3308 LCIS 线段树


    昨天热身赛的简单版:LCIS。昨天那题用树链剖分,不知道哪里写错了,所以水了水这题看看合并、更新方式是否正确,发现没错啊。看来应该是在树链剖分求lca时写错了。。。

    题目:给出n个数,有两种操作:

      1.单点修改

      2.区间询问:最长连续上升子序列

    分析:只需要维护五个域就行:lix,rdx,mix,lval,rval。记录当前区间 最左的值lval ,  最右的值rval,必须从左起连续上升序列的长度lix,必须右起下降的长度rdx。合并时注意下即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    char IN;
    bool NEG;
    inline void Int(int &x){
        NEG = 0;
        while(!isdigit(IN=getchar()))
            if(IN=='-')NEG = 1;
        x = IN-'0';
        while(isdigit(IN=getchar()))
            x = x*10+IN-'0';
        if(NEG)x = -x;
    }
    
    inline void Char(char &x){
        while(!isupper(x=getchar()));
    }
    
    /******** program ********************/
    
    const int MAXN = 200105;
    
    int son[MAXN],sz[MAXN],top[MAXN],fa[MAXN],tid[MAXN],dep[MAXN],tim;
    bool use[MAXN];
    int a[MAXN];
    
    struct segTree{
        int l,r;
        int lval,rval;
        int lix,mix;
        int rdx;
        segTree(){
            l = r = lval = rval = 0;
            lix = mix = 0;
            rdx = 0;
        }
        inline int mid(){
            return (l+r)>>1;
        }
        inline int dis(){
            return r-l+1;
        }
    }tree[MAXN<<1];
    
    inline void update(segTree &now,segTree l,segTree r){
        // lix
        if(l.lix==l.dis()&&l.rval<r.lval)
            now.lix = l.lix+r.lix;
        else now.lix = l.lix;
    
        // mix
        if(l.rval<r.lval)
            now.mix = max(max(l.mix,r.mix),l.rdx+r.lix);
        else now.mix = max(l.mix,r.mix);
    
        // rdx
        if(r.dis()==r.rdx&&r.lval>l.rval)
            now.rdx = r.rdx+l.rdx;
        else now.rdx = r.rdx;
    
        now.lval = l.lval;
        now.rval = r.rval;
    }
    
    void build(int l,int r,int rt){
        tree[rt].l = l;
        tree[rt].r = r;
        if(l==r){
            tree[rt].lval = tree[rt].rval = a[l];
            tree[rt].lix = tree[rt].mix = 1;
            tree[rt].rdx = 1;
            return;
        }
        int mid = tree[rt].mid();
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
        update(tree[rt],tree[rt<<1],tree[rt<<1|1]);
    }
    
    void modify(int pos,int val,int rt){
        if(tree[rt].l==tree[rt].r){
            tree[rt].lval = tree[rt].rval = val;
            return;
        }
        int mid = tree[rt].mid();
        if(pos<=mid)modify(pos,val,rt<<1);
        else modify(pos,val,rt<<1|1);
        update(tree[rt],tree[rt<<1],tree[rt<<1|1]);
    }
    
    segTree ask(int l,int r,int rt){
        if(l<=tree[rt].l&&tree[rt].r<=r)
            return tree[rt];
        int mid = tree[rt].mid();
        segTree ans;
        if(r<=mid)ans = ask(l,r,rt<<1);
        else if(l>mid)ans = ask(l,r,rt<<1|1);
        else{
            segTree a = ask(l,r,rt<<1);
            segTree b = ask(l,r,rt<<1|1);
            update(ans,a,b);
        }
        update(tree[rt],tree[rt<<1],tree[rt<<1|1]);
        return ans;
    }
    
    int main(){
    
    #ifndef ONLINE_JUDGE
        freopen("sum.in","r",stdin);
        //freopen("sum.out","w",stdout);
    #endif
    
        char op;
        int n,m,ncase,x,y;
        Int(ncase);
        while(ncase--){
            Int(n);Int(m);
            for(int i=1;i<=n;i++)
                Int(a[i]);
            build(1,n,1);
            while(m--){
                Char(op);
                Int(x);Int(y);
                if(op=='Q')printf("%d
    ",ask(++x,++y,1).mix);
                else modify(++x,y,1);
            }
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    查看占用内存cpu top10
    free 详解
    find
    服务器硬件查看
    firewalld命令使用
    firewalld-zone概念介绍
    Jenkins rpm包安装
    攻击防御案例
    filebeat收集系统登陆日志
    nginx转换json格式
  • 原文地址:https://www.cnblogs.com/yejinru/p/3316146.html
Copyright © 2020-2023  润新知