HDU 3308 LCIS

线段树区间合并

/* ***********************************************
Author        :Zhou Zhentao
Email         :774388357@qq.com
Created Time  :2015/11/28 9:05:25
File Name     :main.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const int maxn=100000+10;
struct SegTree
{
    int lsum,rsum,msum;
    int lnum,rnum;
}segTree[4*maxn];
int T,N,Q;

void pushUp(int rt,int len)
{
    //确定左边第一个数字
    segTree[rt].lnum=segTree[2*rt].lnum;
    
    //确定右边第一个数字
    segTree[rt].rnum=segTree[2*rt+1].rnum;

    //确定从左开始的最长连续上升的长度
    if(segTree[2*rt].msum==len-len/2&&segTree[2*rt].rnum<segTree[2*rt+1].lnum)
        segTree[rt].lsum=segTree[2*rt].lsum+segTree[2*rt+1].lsum;
    else segTree[rt].lsum=segTree[2*rt].lsum;

    //确定从右开始的最长连续上升的长度
    if(segTree[2*rt+1].msum==len/2&&segTree[2*rt].rnum<segTree[2*rt+1].lnum)
        segTree[rt].rsum=segTree[2*rt].rsum+segTree[2*rt+1].rsum;
    else segTree[rt].rsum=segTree[2*rt+1].rsum;

    //确定区间最长连续上升的长度
    segTree[rt].msum=max(segTree[2*rt].msum,segTree[2*rt+1].msum);
    if(segTree[2*rt].rnum<segTree[2*rt+1].lnum)
        segTree[rt].msum=max(segTree[rt].msum,segTree[2*rt].rsum+segTree[2*rt+1].lsum);
}

void build(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%d",&segTree[rt].lnum);
        segTree[rt].rnum=segTree[rt].lnum;
        segTree[rt].lsum=segTree[rt].rsum=segTree[rt].msum=1;
        return ;
    }

    int m=(l+r)/2;
    build(l,m,rt*2);
    build(m+1,r,rt*2+1);
    
    pushUp(rt,r-l+1);
}

void update(int p,int add,int l,int r,int rt)
{
    if(l==r)
    {  
        segTree[rt].lnum=add;
        segTree[rt].rnum=add;
        return;
    }

    int m=(l+r)/2;
    if(p<=m) update(p,add,l,m,2*rt);
    else update(p,add,m+1,r,2*rt+1);

    pushUp(rt,r-l+1);
}

int quary(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r) 
    {
        return segTree[rt].msum;
    }
    int m=(l+r)/2;
    if(R<=m) return quary(L,R,l,m,2*rt);
    else if(L>=m+1) return quary(L,R,m+1,r,2*rt+1);
    else
    {
        int Q1=quary(L,R,l,m,2*rt);
        int Q2=quary(L,R,m+1,r,2*rt+1);

        int ans=max(Q1,Q2);

        int Min1=min(segTree[2*rt].rsum,m-L+1);
        int Min2=min(segTree[2*rt+1].lsum,R-m);


        if(segTree[2*rt].rnum<segTree[2*rt+1].lnum)
            ans=max(ans,Min1+Min2);
        return ans;
    }
   
}

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

 

posted @ 2015-11-28 18:33  Fighting_Heart  阅读(188)  评论(0编辑  收藏  举报