• 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;
    }
  • 相关阅读:
    读书笔记 effective c++ Item 32 确保public继承建立“is-a”模型
    读书笔记 effective c++ Item 31 把文件之间的编译依赖降到最低
    读书笔记 effective c++ Item 30 理解内联的里里外外 (大师入场啦)
    程序猿开发语言投票
    读书笔记 effective c++ Item 29 为异常安全的代码而努力
    读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)
    C++ 11和C++98相比有哪些新特性
    读书笔记 effective c++ Item 27 尽量少使用转型(casting)
    如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文
    如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文
  • 原文地址:https://www.cnblogs.com/programCaiCai/p/POJ3667.html
Copyright © 2020-2023  润新知