[HDU 3308] LCIS

LCIS

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


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

#include <cstdio>

#include <cstring>

using namespace std;

#define N 100005



struct node

{

    int l,r,m;

    int ln,rn;

    int lsum,rsum,msum;

    int mid()

    {

        return (l+r)>>1;

    }

}t[N<<2];

int a[N];



void pushup(int rt)

{

    t[rt].lsum=t[rt<<1].lsum;

    t[rt].rsum=t[rt<<1|1].rsum;

    t[rt].ln=t[rt<<1].ln;

    t[rt].rn=t[rt<<1|1].rn;

    t[rt].msum=max(t[rt<<1].msum,t[rt<<1|1].msum);

    int ll=t[rt<<1].r-t[rt<<1].l+1;

    int rr=t[rt<<1|1].r-t[rt<<1|1].l+1;



    if(t[rt<<1].rn<t[rt<<1|1].ln) 

    {

        if(t[rt<<1].lsum==ll)

            t[rt].lsum+=t[rt<<1|1].lsum;

        if(t[rt<<1|1].rsum==rr)

            t[rt].rsum+=t[rt<<1].rsum;

        t[rt].msum=max(t[rt].msum,t[rt<<1].rsum+t[rt<<1|1].lsum);

    }

}

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

{

    t[rt].l=l;

    t[rt].r=r;

    if(l==r)

    {

        t[rt].ln=t[rt].rn=a[l];

        t[rt].lsum=t[rt].rsum=t[rt].msum=1;

        return;

    }

    int m=t[rt].mid();

    build(l,m,rt<<1);

    build(m+1,r,rt<<1|1);

    pushup(rt);

}

void update(int rt,int pos,int c)

{

    if(t[rt].l==t[rt].r)

    {

        t[rt].ln=t[rt].rn=c;

        return;

    }

    int m=t[rt].mid();

    if(pos<=m) update(rt<<1,pos,c);

    else update(rt<<1|1,pos,c);

    pushup(rt);

}

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

{

    if(t[rt].l==L && t[rt].r==R)

    {

        return t[rt].msum;

    }

    int m=t[rt].mid();

    if(R<=m) return query(rt<<1,L,R);

    else if(L>m) return query(rt<<1|1,L,R);

    else

    {

        int sum=0,m=t[rt].mid();

        int ltmp=query(rt<<1,L,m);

        int rtmp=query(rt<<1|1,m+1,R);

        if(t[rt<<1].rn<t[rt<<1|1].ln)       //注意:取最大值时要保证是在给定的区间[L,R]里面,左边,取min(全长,rsum),右边取min(全长,lsum)

        {

            sum=min(m-L+1,t[rt<<1].rsum)+min(R-m,t[rt<<1|1].lsum);

        }

        return max(max(ltmp,rtmp),sum);

    }

}

int main()

{    

    int T,n,m,i;

    scanf("%d",&T);

    while(T--)

    {

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

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

        {

            scanf("%d",&a[i]);

        }

        build(0,n-1,1);

        while(m--)

        {

            char op;

            int a,b;

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

            if(op=='U') update(1,a,b);

            else if(op=='Q') printf("%d\n",query(1,a,b));

        }

    }

    return 0;

}

 

你可能感兴趣的:(HDU)