POJ 3667 Hotel 线段树

线段树经典题
线段树功能:    1.区间覆盖
                2.查询区间最长连续1个数
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
const int N=65536+10;

struct SegNode{
    int lsum,rsum,csum;
    int color;
};

struct SegTree{
    SegNode a[N<<2];
    int n,Q;
    void Init(int n){
        this->n=n;
        for(Q=1;Q<=n+2;Q<<=1);
        memset(a,0,(Q<<1|1)*sizeof(int));
    }
    void update(int rt,int color,int L){
        int val=color==0?0:L;
        a[rt].lsum=a[rt].rsum=a[rt].csum=val;
        a[rt].color=color;
    }
    void pushup(int rt,int L){
        if(rt>=Q) return;
        a[rt].lsum=a[rt<<1].lsum;
        a[rt].rsum=a[rt<<1|1].rsum;
        if(a[rt].lsum==L>>1) a[rt].lsum+=a[rt<<1|1].lsum;
        if(a[rt].rsum==L>>1) a[rt].rsum+=a[rt<<1].rsum;
        a[rt].csum=max(max(a[rt<<1].csum,a[rt<<1|1].csum),a[rt<<1].rsum+a[rt<<1|1].lsum);
        if(a[rt<<1].color==a[rt<<1|1].color) a[rt].color=a[rt<<1].color;
        else a[rt].color=-1;
    }
    void pushdown(int rt,int L){
        if(rt>=Q) return;
        if(a[rt].color!=-1){
            a[rt<<1].color=a[rt<<1|1].color=a[rt].color;
            int val=a[rt].color==0?0:L>>1;
            a[rt<<1].lsum=a[rt<<1|1].lsum=val;
            a[rt<<1].rsum=a[rt<<1|1].rsum=val;
            a[rt<<1].csum=a[rt<<1|1].csum=val;
        }
    }
    void cover(int L,int R,int l,int r,int rt,int color){
        if(L<=l && r<=R){
            update(rt,color,r-l+1);
            return;
        }
        if(rt>=Q) return;
        pushdown(rt,r-l+1);
        int m=(l+r)>>1;
        if(L<=m) cover(L,R,l,m,rt<<1,color);
        if(m<R)    cover(L,R,m+1,r,rt<<1|1,color);
        pushup(rt,r-l+1);
    }
    int query(int x,int l,int r,int rt){
        if(a[rt].lsum>=x) return l;
        pushdown(rt,r-l+1);
        if(rt<Q){
            int m=(l+r)>>1;
            if(a[rt<<1].csum>=x) return query(x,l,m,rt<<1);
            else if(a[rt<<1].rsum+a[rt<<1|1].lsum>=x) return m-a[rt<<1].rsum+1;
            else if(a[rt<<1|1].csum>=x) return query(x,m+1,r,rt<<1|1);
        }
        return -1;
     }
    void cover(int L,int R,int color){
        cover(L,R,0,Q-1,1,color);
    }
    int query(int x){
        return query(x,0,Q-1,1);
    }
}st;

int n,m;

int main() {
    setbuf(stdout,NULL);
    while(scanf("%d%d",&n,&m)!=EOF){
        st.Init(n);
        st.cover(1,n,1);
        for(int i=0;i<m;i++){
            int op,x1,x2;
            scanf("%d",&op);
            if(op==1){
                scanf("%d",&x1);
                int r=st.query(x1);
                if(r==-1) printf("0\n");
                else printf("%d\n",r),st.cover(r,r+x1-1,0);

            }else{
                scanf("%d%d",&x1,&x2);
                st.cover(x1,x1+x2-1,1);
            }
        }
    }
    return 0;
}
posted @ 2012-08-06 09:34  编程菜菜  阅读(168)  评论(0编辑  收藏  举报