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;
}

  

原文地址:https://www.cnblogs.com/yejinru/p/3316146.html