zoukankan      html  css  js  c++  java
  • hdu 3308 线段树,单点更新 求最长连续上升序列长度

    LCIS

    Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 9713    Accepted Submission(s): 4215


    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
     
    题意:求区间连续递增的最大个数,Q是询问区间内最大的LCIS

    U是更新节点

     
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int maxn = 1e5 + 6;
    int llen[maxn << 2], rlen[maxn << 2], len[maxn << 2], tree[maxn];
    void pushup(int l, int r, int id)
    {
        int m = (l + r) >> 1;
        llen[id] = llen[id << 1];
        rlen[id] = rlen[id << 1 | 1];
        if (tree[m + 1] > tree[m])
        {
            if (llen[id << 1] == m - l + 1)
                llen[id] += llen[id << 1 | 1];
            if (rlen[id << 1 | 1] == r - m)
                rlen[id] += rlen[id << 1];
            len[id] = max(max(len[id << 1], len[id << 1 | 1]), rlen[id << 1] + llen[id << 1 | 1]);
        }
        else
            len[id] = max(len[id << 1], len[id << 1 | 1]);
    }
    void build(int l, int r, int id)
    {
        if (l == r)
        {
            scanf("%d", &tree[l]);
            len[id] = llen[id] = rlen[id] = 1;
            return;
        }
        int m = (l + r) >> 1;
        build(l,m,id<<1);
        build(m+1,r,id<<1|1);
        pushup(l, r, id);
    }
    int query(int ll, int rr, int l, int r, int id)
    {
        if (ll <= l && r <= rr)
            return len[id];
        int m = (l + r) >> 1;
        if (ll <= m && m < rr)
        {
            int l1 = query(ll, rr, l,m,id<<1);
            int l2 = query(ll, rr, m+1,r,id<<1|1);
            if (tree[m] < tree[m + 1])
            {
                int le = max(ll, m - rlen[id << 1] + 1);
                int ri = min(rr, m + llen[id << 1 | 1]);
                return max(max(l1, l2), ri - le + 1);
            }
            return max(l1, l2);
        }
        else if (rr <= m)
            return query(ll, rr, l,m,id<<1);
        else
            return query(ll, rr, m+1,r,id<<1|1);
    }
    
    void update(int a, int b, int l, int r, int id)
    {
        if (a == l && a == r)//找到要更新的位置
        {
            tree[a] = b;
            return;
        }
        int m = (l + r) >> 1;
        if (m >= a)
            update(a, b, l,m,id<<1);
        else
            update(a, b, m+1,r,id<<1|1);
        pushup(l, r, id);
    }
    int main()
    {
        int t;
        scanf("%d
    ", &t);
        while (t--)
        {
            int n, m;
            scanf("%d%d", &n, &m);
            build(0, n - 1, 1);
    
            while (m--)
            {
                char c[5];
                int a, b;
                scanf("%s %d %d", c, &a, &b);
                if (c[0] == 'Q')
                    printf("%d
    ", query(a, b, 0, n - 1, 1));
                else
                    update(a, b, 0, n - 1, 1);
            }
        }
        return 0;
    }
  • 相关阅读:
    idea优秀插件(Java开发常用)
    mysql中文乱码问题解决
    SpringMVC生成任意文件,访问链接即下载
    SpringMVC生成Excel下载
    [转]java实现excel的导入导出(poi详解)
    [转]遇到乱码了查看乱码编码
    idea打包java可执行jar包
    Java项目JUnit简单使用
    [转]SpringMVC拦截器简单教程
    Java精确计算小数
  • 原文地址:https://www.cnblogs.com/-citywall123/p/11066942.html
Copyright © 2011-2022 走看看