码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 3308 线段树,单点更新 求最长连续上升序列长度

时间:2019-06-21 22:14:11      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:ges   The   lines   limit   color   ons   des   nbsp   inpu   

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\n", &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\n", query(a, b, 0, n - 1, 1));
            else
                update(a, b, 0, n - 1, 1);
        }
    }
    return 0;
}

 

hdu 3308 线段树,单点更新 求最长连续上升序列长度

标签:ges   The   lines   limit   color   ons   des   nbsp   inpu   

原文地址:https://www.cnblogs.com/-citywall123/p/11066942.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!