zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Struts2SpringHibernate整合示例,一个HelloWorld版的在线书店(项目源码+详尽注释+单元测试)
    Java实现蓝桥杯勇者斗恶龙
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 224 基本计算器
    Java实现 LeetCode 224 基本计算器
  • 原文地址:https://www.cnblogs.com/programCaiCai/p/POJ3667.html
Copyright © 2011-2022 走看看