LCIS HDU - 3308(线段树区间合并)

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<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
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

题意:
单点修改。询问区间最长上升子串
思路:
维护区间最长上升串,区间最长上升前缀,区间最长上升后缀。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 7;

struct Node
{
    int l,r;
    int lx,rx,mx;
}t[maxn << 2];
int val[maxn];

void pushup(int i)
{
    int m = (t[i].l + t[i].r) >> 1;
    
    //mx
    t[i].mx = max(t[i * 2].mx,t[i * 2 + 1].mx);
    if(val[m] < val[m + 1])t[i].mx = max(t[i].mx,t[i * 2].rx + t[i * 2 + 1].lx);
    
    //lx
    t[i].lx = t[i * 2].lx;
    if(val[m] < val[m + 1] && t[i * 2].lx == m - t[i * 2].l + 1)
        t[i].lx += t[i * 2 + 1].lx;
    
    //rx
    t[i].rx = t[i * 2 + 1].rx;
    if(val[m] < val[m + 1] && t[i * 2 + 1].rx == t[i * 2 + 1].r - m)
        t[i].rx += t[i * 2].rx;
}

void build(int i,int l,int r)
{
    t[i].l = l;t[i].r = r;
    if(l == r)
    {
        t[i].lx = t[i].rx = t[i].mx = 1;
        scanf("%d",&val[l]);
        return;
    }
    int m = (l + r) >> 1;
    build(i * 2,l,m);
    build(i * 2 + 1,m + 1,r);
    pushup(i);
}

void update(int i,int x,int v)
{
    if(t[i].l == t[i].r)
    {
        val[t[i].l] = v;
        return;
    }
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m)update(i * 2,x,v);
    else update(i * 2 + 1,x,v);
    pushup(i);
}

int query(int i,int x,int y)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        return t[i].mx;
    }
    int m = (t[i].l + t[i].r) >> 1;
    if(y <= m)return query(i * 2,x,y);
    if(x > m) return query(i * 2 + 1,x,y);
    int x1 = query(i * 2,x,y), x2 = query(i * 2 + 1,x,y);
    int l = min(t[i * 2].rx,m - x + 1);
    int r = min(t[i * 2 + 1].lx,y - m);
    int x3 = l;
    if(val[m] < val[m + 1])x3 += r;
    return max(max(x1,x2),x3);
}

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n,m;scanf("%d%d",&n,&m);
        build(1,1,n);
        while(m--)
        {
            char op[10];
            int x,y;
            scanf("%s %d %d",op,&x,&y);
            if(op[0] == 'Q')
            {
                x++;y++;
                printf("%d\n",query(1,x,y));
            }
            else if(op[0] == 'U')
            {
                x++;
                update(1,x,y);
            }
        }
    }
    return 0;
}

发布了628 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104078088