HDU 3308 LCIS

LCIS

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

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
 
求最长 最长公共上升子序列
#include <stdio.h>

#include <stdlib.h>

#include <algorithm>

#include <iostream>

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define maxn  100005

using namespace std;



int mov[maxn<<2],las[maxn<<2],ras[maxn<<2];

int va[maxn];



void pushup(int rt,int l,int r)

{

    las[rt]=las[rt<<1];

    ras[rt]=ras[rt<<1|1];

    mov[rt]=max(mov[rt<<1],mov[rt<<1|1]);

    int mid=(l+r)>>1;

    int m=(r-l)+1;

    if(va[mid]<va[mid+1]) //左区间的右值小于右区间的左值可以合并

    {

        if(las[rt]==m-(m>>1)) las[rt]+=las[rt<<1|1];

        if(ras[rt]==(m>>1)) ras[rt]+=ras[rt<<1];

        mov[rt]=max(mov[rt],las[rt<<1|1]+ras[rt<<1]);

    }

}

void build(int l,int r,int rt)

{

    if(l==r)

    {

        mov[rt]=las[rt]=ras[rt]=1;

        return ;

    }

    int m=(l+r)>>1;

    build(lson);

    build(rson);

    pushup(rt,l,r);

}

void  update(int a,int l,int r,int rt)

{

    if(l==r)

    {

        return;

    }

    int m=(l+r)>>1;

    if(a<=m) update(a,lson);

    else update(a,rson);

    pushup(rt,l,r);

}



int query(int L,int R,int l,int r,int rt)

{

    if(L<=l&&r<=R)

    {

        return mov[rt];

    }

    int m=(l+r)>>1;

    if(R<=m) return query(L,R,lson); //与一般不同,不能是子集,只能全部属于才能直接查询子区间 返回子区间的mlen

    if(L>m) return query(L,R,rson);  //否则是确认儿子区间是否能合并,并在三者之间取最大值



    int ta,tb;

    ta=query(L,R,lson);

    tb=query(L,R,rson);

    int ans;

    ans=max(ta,tb);

    if(va[m]<va[m+1])  //同上

    {

        int temp;

        temp=min(ras[rt<<1],m-L+1)+min(las[rt<<1|1],R-m);

        ans=max(temp,ans);

    }

    return ans;

}



int main()

{

    int T,n,m;

    int i,j;

    char f[2];

    int a,b;

    scanf("%d",&T);

    for(i=0;i<T;i++)

    {

        scanf("%d %d",&n,&m);

        for(j=1;j<=n;j++)

           scanf("%d",&va[j]);

        build(1,n,1);

        while(m--)

        {

            scanf("%s",&f);

            if(f[0]=='U')

            {

                scanf("%d %d",&a,&b);

                a++;

                va[a]=b;

                update(a,1,n,1);

            }

            else

            {

                scanf("%d %d",&a,&b);

                a++,b++;

                printf("%d\n",query(a,b,1,n,1));

            }

        }

    }

    return 0;

}
View Code

 

你可能感兴趣的:(HDU)