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

LCIS

Time Limit : 6000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 1   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size:

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<=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

Author

shǎ崽

Source

HDOJ Monthly Contest – 2010.02.06
#include <queue>
#include <iostream>
#include<cstring>
#include<stdio.h>
#define maxn 100050
using namespace std;
int n,m,x,y;
char c;
/*
区间合并;
该程序没有剪枝就过了,估计是数据水吧。。。
如果有两个区间,如何设定标准值并进行操作把它合并成一个区间呢。
首先肯定需要两个子区间的最长长度,
然后对大区间的中间部分进行判定,
依次递推下标。。。得到另外一个判断值,再代入比较
*/
struct node
{
    int l,r;
    int v,maxl;//最长长度
    int lc,rc;
    node()
    {
        lc=rc=0;
        l=r=v=maxl=0;
    }
};
node seq[maxn<<2];
int num[maxn];

void pushup(int rt)
{
    int rr=seq[rt<<1].r,ll=seq[rt<<1|1].l;
    int nlc,nrc,tmp;
    seq[rt].maxl=max(seq[rt<<1].maxl,seq[rt<<1|1].maxl);
        if(seq[rt].maxl==seq[rt<<1].maxl)
        {
            seq[rt].lc=seq[rt<<1].lc,seq[rt].rc=seq[rt<<1].rc;
        }
        else if(seq[rt].maxl==seq[rt<<1|1].maxl)
        {
            seq[rt].lc=seq[rt<<1|1].lc,seq[rt].rc=seq[rt<<1|1].rc;
         }
    if(num[ll]>num[rr])
    {
        nlc=rr,nrc=ll;
        while(nrc+1<=seq[rt<<1|1].r&&num[nrc]<num[nrc+1])
            nrc++;
        while(nlc-1>=seq[rt<<1].l&&num[nlc]>num[nlc-1])
            nlc--;
        seq[rt].maxl=max(seq[rt].maxl,nrc-nlc+1);
        if(seq[rt].maxl==nrc-nlc+1)
            seq[rt].lc=nlc,seq[rt].rc=nrc;
    }
}

void build(int l,int r,int rt)
{
    seq[rt].l=l;
    seq[rt].r=r;
    if(l==r)
    {
        seq[rt].lc=seq[rt].rc=l;
        seq[rt].v=num[l];
        seq[rt].maxl=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}

void update(int p,int rt,int val)
{
    if(seq[rt].l==seq[rt].r)
    {
        seq[rt].v=num[seq[rt].l]=val ;
        return ;
    }
    int mid=(seq[rt].l+seq[rt].r)>>1;
    if(mid>=p)  update(p,rt<<1,val);
    else update(p,rt<<1|1,val);
    pushup(rt);
}

int query(int l,int r,int rt)
{
    if(seq[rt].l>=l&&seq[rt].r<=r)
         return seq[rt].maxl;
    int mid=(seq[rt].l+seq[rt].r)>>1;
    int max1=0,max2=0,maxx=-1;
    int nl=0,nr=0;
    if(mid>=l)
        max1=query(l,r,rt<<1);
    if(r>mid)
        max2=query(l,r,rt<<1|1);
    maxx=max(max1,max2);

    if(max1&&max2)
    {
        nl=mid,nr=mid+1;
        if(num[nl]<num[nr])
        {
            while(nr+1<=r&&num[nr]<num[nr+1])
                nr++;
            while(nl-1>=l&&num[nl]>num[nl-1])
                nl--;
        }
        else
            nl=nr=0;
    }
    return max(maxx,nr-nl+1);
}

int main()
{
    ios::sync_with_stdio(false);
    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)  scanf("%d",&num[i]);getchar();
        build(1,n,1);

        while(m--)
        {
            //scanf("%c",&c);
            cin>>c;
            if(c=='U')
            {
                cin>>x>>y;
                //scanf("%d%d",&x,&y);
                x++;
                update(x,1,y);
            }
            else
            {
                cin>>x>>y;
                //scanf("%d%d",&x,&y);
                x++,y++;
                cout<<query(x,y,1)<<endl;
            }
        }

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37451344/article/details/80406698