zoukankan      html  css  js  c++  java
  • HDU 3308 LCIS (线段树·单点更新·区间合并)

    题意  给你一个数组  有更新值和查询两种操作  对于每次查询  输出相应区间的最长连续递增子序列的长度

    基础的线段树区间合并  线段树维护三个值  相应区间的LCIS长度(lcis)  相应区间以左端点为起点的LCIS长度(lle)  相应区间以右端点为终点的LCIS长度(lri)  然后用val存储数组相应位置的值  当val[mid + 1] > val[mid] 的时候就要进行区间合并操作了

    #include <cstdio>
    #include <algorithm>
    #define lc lp, s, mid
    #define rc rp, mid+1, e
    #define lp p<<1
    #define rp p<<1|1
    #define mid ((s+e)>>1)
    using namespace std;
    const int N = 100005, M = N * 4;
    int lcis[M], lle[M], lri[M], val[N];
    
    void pushup(int p, int s, int e)
    {
        lcis[p] = max(lcis[lp], lcis[rp]);
        lle[p] = lle[lp], lri[p] = lri[rp];
        if(val[mid + 1] > val[mid]) //合并条件
        {
            lcis[p] = max(lcis[p], lri[lp] + lle[rp]);
            if(lle[lp] == mid + 1 - s) lle[p] += lle[rp];
            if(lri[rp] == e - mid) lri[p] += lri[lp];
        }
    }
    
    void build(int p, int s, int e)
    {
        if(s == e)
        {
            lcis[p] = lle[p] = lri[p] = 1;
            scanf("%d", &val[s]);
            return;
        }
        build(lc);
        build(rc);
        pushup(p, s, e);
    }
    
    void update(int p, int s, int e, int x, int v)
    {
        if(s == e)
        {
            val[s] = v;
            return;
        }
        if(x <= mid) update(lc, x, v);
        else if(x > mid) update(rc, x, v);
        pushup(p, s, e);
    }
    
    int query(int p, int s, int e, int l, int r)
    {
        if(l <= s && e <= r) return lcis[p];
        int ret = 0;
        if(val[mid + 1] > val[mid])
            ret = min(r, mid + lle[rp]) - max(l, mid + 1 - lri[lp]) + 1;
        if(l <= mid)  ret = max(ret, query(lc, l, r));
        if(r > mid)  ret = max(ret, query(rc, l, r));
        return ret;
    }
    
    int main()
    {
        int T, n, m, a, b;
        char op[5];
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d", &n, &m);
            build(1, 0, n - 1);
            while(m--)
            {
                scanf("%s%d%d", op, &a, &b);
                if(op[0] == 'Q')
                    printf("%d
    ", query(1, 0, n - 1, a, b));
                else update(1, 0, n - 1, a, b);
            }
        }
        return 0;
    }

    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].
     

    Input
    T in the first line, indicating the case number.
    Each case starts with two integers n , m(0<n,m<=105).
    The next line has n integers(0<=val<=105).
    The next m lines each has an operation:
    U A B(0<=A,n , 0<=B=105)
    OR
    Q A B(0<=A<=B< n).
     

    Output
    For each Q, output the answer.
     

    Sample Input
    1 10 10 7 7 3 3 5 9 9 8 1 8 Q 6 6 U 3 4 Q 0 1 Q 0 5 Q 4 7 Q 3 5 Q 0 2 Q 4 6 U 6 10 Q 0 9
     

    Sample Output
    1 1 4 2 3 1 2 5
     

  • 相关阅读:
    install jqdatasdk
    分布式唯一ID自增(雪花算法)
    JVM内存布局及GC知识
    double涉及大数据的时候会变成科学计数法
    IDEA中的JUNIT测试
    spring boot 整合 swagger2
    springboot 报错nested exception is java.lang.IllegalStateException: Failed to check the status of the service xxxService No provider available for the service
    解决jar包依赖冲突(idea)
    IDEA中springboot的热部署
    Exception in thread "main" java.lang.AbstractMethodError: org.springframework.boot.context.config.ConfigFileApplicationListener.supportsSourceType(Ljava/lang/Class;)Z
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7260135.html
Copyright © 2011-2022 走看看