码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 3308 线段树

时间:2015-08-06 12:29:04      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:

输入一串数字,有两个操作:Q a b 查询a到b区间内严格递增子串的最大长度 ; U a b 把第a位数字替换成b 。注意输入的编号是从0开始

解法:线段树维护区间的严格递增子串的最大长度即可。注意细节。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
struct Tree{
    int l,r;
    int valuel,valuer,value;
    int ld,rd;

}nod[100020<<2];
int n,m;
int w[1000020] ;

void Pushup(int k)
{
    nod[k].valuel = nod[k].valuer = 1;
    if(nod[k<<1].rd < nod[k<<1|1].ld){
        nod[k].value=max(nod[k<<1].valuer+nod[k<<1|1].valuel,
                         max(nod[k<<1].value,nod[k<<1|1].value));
        if(nod[k<<1].valuel == nod[k<<1].r-nod[k<<1].l+1 ){
            nod[k].valuel=nod[k<<1].valuel+nod[k<<1|1].valuel ;
        }
        if(nod[k<<1|1].valuer == nod[k<<1|1].r-nod[k<<1|1].l+1){
            nod[k].valuer=nod[k<<1|1].valuer+nod[k<<1].valuer;
        }
        nod[k].valuel=max(nod[k].valuel,nod[k<<1].valuel) ;
        nod[k].valuer=max(nod[k].valuer,nod[k<<1|1].valuer) ;
        //cout<<nod[2].valuer<<endl;
    }
    else{
        nod[k].value=max(nod[k<<1].value,nod[k<<1|1].value) ;
        nod[k].valuel = nod[k<<1].valuel ;
        nod[k].valuer = nod[k<<1|1].valuer ;
    }
    nod[k].ld=nod[k<<1].ld , nod[k].rd=nod[k<<1|1].rd ;
}

void Build(int l,int r,int k)
{
    nod[k].l=l,nod[k].r=r , nod[k].ld=w[nod[k].l] , nod[k].rd=w[nod[k].r] ;
    if(nod[k].l == nod[k].r){
        nod[k].value= nod[k].valuel =nod[k].valuer= 1;
        return ;
    }
    int mid = (l+r)>>1 ;
    Build(l,mid,k<<1);
    Pushup(k) ;
    Build(mid+1,r,k<<1|1);
    Pushup(k);
}

int Query(int l,int r,int k)
{
    int ans =0;
    if(nod[k].l==l && nod[k].r==r ){
        return nod[k].value ;
    }
    int mid=(nod[k].l + nod[k].r)>>1 ;
    if(r<=mid){
        return Query(l,r,k<<1) ;
    }
    else if(l>mid){
        return Query(l,r,k<<1|1) ;
    }
    else{
        if(nod[k<<1].rd < nod[k<<1|1].ld  ){
            ans = max(Query(l,mid,k<<1) , Query(mid+1,r,k<<1|1)) ;
            int temp = min(mid-l+1,nod[k<<1].valuer)+min(r-(mid+1)+1,nod[k<<1|1].valuel) ;
            ans=max(ans,temp);
         }
         else{
            ans= max(Query(l,mid,k<<1),Query(mid+1,r,k<<1|1)) ;
         }

    }
    return ans ;

}

void Update(int l,int k,int value)
{
    if(nod[k].l==nod[k].r && nod[k].l == l){
        nod[k].ld = nod[k].rd = value ;
        w[nod[k].r]=value ;
        nod[k].valuel = nod[k].valuer = nod[k].value =1 ;

        return ;
    }
    int mid=(nod[k].l+ nod[k].r)>>1 ;
    if(l<=mid){
        Update(l,k<<1,value);
    }
    else{
        Update(l,k<<1|1,value) ;
    }
    Pushup(k);
    return ;

}
int main()
{
    int t;
    scanf("%d",&t) ;
    while(t--){
        scanf("%d%d",&n,&m) ;
        memset(w,0,sizeof w) ;
        for(int i=1;i<=n;i++){
            scanf("%d",&w[i]) ;
        }
        //getchar() ;

        Build(1,n,1) ;
        /*for(int i=1;i<=30;i++){
            cout<<i<<" "<<nod[i].value<<" "<<nod[i].valuel<<" "<<nod[i].valuer<<endl;
        }
        cout<<"-------------------------------------"<<endl;*/
        for(int i=0;i<m;i++){

            char c;
            int a,b;
            cin>>c;
            scanf("%d%d",&a,&b);
            //cout<<c<<endl;
            if(c==Q){
               a++,b++;
               if(a>b){
                swap(a,b) ;
               }
               int ans = Query(a,b,1);
               //cout<<c<<endl;
               printf("%d\n",ans) ;
            }
            else{
                a++;
                Update(a,1,b) ;
                /*for(int i=1;i<=30;i++){
                    cout<<i<<" "<<nod[i].value<<" "<<nod[i].valuel<<" "<<nod[i].valuer<<endl;
                }
                cout<<"-------------------------------------"<<endl;*/
            }
        }
    }
    return 0;
}

 

hdu 3308 线段树

标签:

原文地址:http://www.cnblogs.com/Scale-the-heights/p/4707336.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!