ACDream 1101 瑶瑶想要玩滑梯 线段树

http://blog.csdn.net/u013368721/article/details/31400053

线段树上的一种dp

//Hello. I'm Peter.
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
#define peter cout<<"i am peter"<<endl;
#define input freopen("/Users/peteryuanpan/data.txt","r",stdin)
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

#define N 100010
int n,m,a[N];

#define lch id<<1
#define rch id<<1|1
#define mid ((l+r)>>1)
struct Segment_Tree{
    int lz,len;

    int lv,rv;
    //len from left,len from right
    int lenl,lenr;
    int maxl;

    Segment_Tree(){};
}tree[N<<2];

void pullup(Segment_Tree &treeid,Segment_Tree &treelch,Segment_Tree &treerch){
    //tree[id] is not leaf

    treeid.lv=treelch.lv;
    treeid.lenl=treelch.lenl;
    if(treelch.lenl==treelch.len && treelch.rv<treerch.lv) treeid.lenl=treelch.len+treerch.lenl;

    treeid.rv=treerch.rv;
    treeid.lenr=treerch.lenr;
    if(treerch.lenr==treerch.len && treelch.rv<treerch.lv) treeid.lenr=treelch.lenr+treerch.len;

    treeid.maxl=max(treelch.maxl , treerch.maxl);
    treeid.maxl=max(treeid.maxl , treelch.lenl);
    treeid.maxl=max(treeid.maxl , treerch.lenr);
    if(treelch.rv<treerch.lv) treeid.maxl=max(treeid.maxl , treelch.lenr+treerch.lenl);

}

void plant_tree(int id,int l,int r){
    tree[id].lz=0;
    tree[id].len=r-l+1;

    if(l==r){
        tree[id].lv = tree[id].rv = a[l];
        tree[id].lenl = tree[id].lenr = tree[id].maxl = 1;
        return;
    }

    plant_tree(lch,l,mid);
    plant_tree(rch,mid+1,r);

    pullup(tree[id],tree[lch],tree[rch]);
}

void pushdown(int id){
    if(tree[id].lz){
        tree[lch].lz = tree[id].lz;
        tree[lch].lv = tree[lch].rv = tree[id].lz;
        tree[lch].lenl = tree[lch].lenr = tree[lch].maxl=1;

        tree[rch].lz = tree[id].lz;
        tree[rch].lv = tree[rch].rv = tree[id].lz;
        tree[rch].lenl = tree[rch].lenr = tree[rch].maxl=1;

        tree[id].lz=0;
    }
}

void update(int id,int l,int r,int ql,int qr,int v){
    if(ql==l && qr==r){
        tree[id].lz = v;
        tree[id].lv = tree[id].rv = v;
        tree[id].lenl = tree[id].lenr = tree[id].maxl=1;
        return;
    }

    pushdown(id);

    if(qr<=mid) update(lch,l,mid,ql,qr,v);
    else if(mid<ql) update(rch,mid+1,r,ql,qr,v);
    else update(lch,l,mid,ql,mid,v),update(rch,mid+1,r,mid+1,qr,v);

    pullup(tree[id],tree[lch],tree[rch]);
}

int ans;
void query(int id,int l,int r,int ql,int qr,Segment_Tree &node){
    if(ql==l && qr==r){
        ans=max(ans,tree[id].maxl);
        node=tree[id];
        return;
    }

    pushdown(id);

    if(qr<=mid) query(lch,l,mid,ql,qr,node);
    else if(mid<ql) query(rch,mid+1,r,ql,qr,node);
    else{
        Segment_Tree lson,rson;
        query(lch,l,mid,ql,mid,lson);
        query(rch,mid+1,r,mid+1,qr,rson);

        pullup(node,lson,rson);
        ans=max(ans,node.maxl);
    }

    pullup(tree[id],tree[lch],tree[rch]);
}

int main(){
    //input;
    n=read(),m=read();

    for(int i=1;i<=n;i++){
        a[i]=read();
    }

    plant_tree(1,1,n);

    for(int i=1;i<=m;i++){
        char s[5];
        scanf("%s",s);
        if(s[0]=='Q'){
            int l,r;
            l=read(),r=read();

            ans=1;
            Segment_Tree now;
            query(1,1,n,l,r,now);

            printf("%d\n",ans);
        }
        else{
            int l,r,yi;
            l=read(),r=read(),yi=read();

            update(1,1,n,l,r,yi);
        }
    }
    return 0;
}

你可能感兴趣的:(dp-on-线段树)