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

来源:互联网 发布:windows正版验证补丁 编辑:程序博客网 时间:2024/05/18 12:04

原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=3308

题意:……

思路:线段数的区间合并问题,和上篇类似,具体参考http://blog.csdn.net/piaoyi0208/article/details/8149804

AC代码:

#include<stdio.h>#include<string.h>#include<algorithm>#define Mid(a,b) (a+b)>>1#define Max 100000int 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);            }        }    }}


原创粉丝点击