您的位置:首页 > 其它

HDU OJ 3308 LCIS 【线段树之区间合并】

2012-11-07 13:29 274 查看
原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=3308

题意:……

思路:线段数的区间合并问题,和上篇类似,具体参考/article/2675354.html

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define Mid(a,b) (a+b)>>1
#define Max 100000
int ac[Max+10],ans,k;
struct hi
{
    int L,R;
    int Lsum,Rsum;
    int sum;
}tree[Max*4];
int Find_Max(int a,int b)
{
    return a>b?a:b;
}
int Find_Min(int a,int b)
{
    return a>b?b:a;
}
void Push_up(int T)
{
    tree[T].Lsum=tree[T<<1].Lsum;
    tree[T].Rsum=tree[T<<1|1].Rsum;
    if(tree[T].Lsum==tree[T<<1].R-tree[T<<1].L+1)
       if(ac[tree[T<<1].R]<ac[tree[T<<1|1].L])
          tree[T].Lsum+=tree[T<<1|1].Lsum;
    if(tree[T].Rsum==tree[T<<1|1].R-tree[T<<1|1].L+1)
       if(ac[tree[T<<1].R]<ac[tree[T<<1|1].L])
          tree[T].Rsum+=tree[T<<1].Rsum;

    tree[T].sum=Find_Max(tree[T<<1].sum,tree[T<<1|1].sum);
    if(ac[tree[T<<1].R]<ac[tree[T<<1|1].L])
        tree[T].sum=Find_Max(tree[T].sum,tree[T<<1].Rsum+tree[T<<1|1].Lsum);
}
void Build_tree(int L,int R,int T)
{
    tree[T].L=L;
    tree[T].R=R;
    if(L==R)
    {
        tree[T].Lsum=tree[T].Rsum=tree[T].sum=1;
        return;
    }
    int x=Mid(L,R);
    Build_tree(L,x,2*T);
    Build_tree(x+1,R,2*T+1);
    Push_up(T);
}
void Updata_tree(int L,int R,int T)
{
    if(tree[T].L==L&&tree[T].R==R)
    {
        tree[T].Lsum=tree[T].Rsum=tree[T].sum=1;
        return;
    }
    int x=Mid(tree[T].L,tree[T].R);
    if(x>=R)
      Updata_tree(L,R,T<<1);
    else
      Updata_tree(L,R,T<<1|1);
    Push_up(T);
}
int Query_tree(int L,int R,int T)
{
    if(tree[T].L==L&&tree[T].R==R)
        return tree[T].sum;
    int x=Mid(tree[T].L,tree[T].R);
    if(x>=R)
        return Query_tree(L,R,T<<1);
    else if(x+1<=L)
       return Query_tree(L,R,T<<1|1);
    else
    {
        int y=Find_Max(Query_tree(L,x,T<<1),Query_tree(x+1,R,T<<1|1));
        if(ac[tree[T<<1].R]<ac[tree[T<<1|1].L])
            y=Find_Max(y,Find_Min(tree[T<<1].Rsum,x-L+1)+Find_Min(tree[T<<1|1].Lsum,R-x));
        return y;
    }

}
int main()
{
    int i,j,n,m,ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
           scanf("%d",&ac[i]);
        Build_tree(1,n,1);
        while(m--)
        {
            char ch[15];
            int x,y;
            scanf("%s %d %d",ch,&x,&y);
            if(ch[0]=='Q')
            {
                ans=Query_tree(x+1,y+1,1);
                printf("%d\n",ans);
            }
            else if(ch[0]=='U')
            {
                ac[1+x]=y;
                Updata_tree(x+1,x+1,1);
            }

        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: