zoukankan      html  css  js  c++  java
  • 【SHOI2009】【BZOJ2028】会场预约(线段树染色)

    problem

    • 维护一个时间序列,支持2种操作。
    • A、拒绝[l,r]原来的预约,并输出拒绝了多少个(每个预约是一个时间段)
      B、输出当前有效的预约个数

    solution

    考虑点主要在:取消区间[l,r]内的预约,而该预约在[l,r]外的部分也被一并取消了。

    • 线段树每个节点维护5个信息:区间内的预约个数cnt(答案本身)。区间内预约最早开始个数ml, 最晚结束个数mr(用于处理题目条件,取消预约在区间外的部分)。区间左端点颜色lc, 区间右端点颜色rc(用以区间合并时求解区间内预约个数,连接处的值)。
    • 对于每一个预定操作,我们将这一段区间内的所有预约,最早是从什么时候开始的(记为ml) 以及 最晚在什么时候结束(记为mr),先把ml~mr区间染上0的颜色标记为没有设置预约(可能超出l,r),再把这一次预定的区间染成这一次预约的颜色。

    codes

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct SegmentTree{
        const static int maxn = (2e5+5);
        #define lch p<<1
        #define rch p<<1|1
        struct node{
            int cnt, ml, mr, lc, rc;
            node operator + (const node &b){
                return (node){(cnt&&b.cnt)?cnt+b.cnt-(rc&&(rc==b.lc)):cnt+b.cnt,min(ml,b.ml),max(mr,b.mr),lc,b.rc};
            }
            void clear(){ml=mr=lc=rc=cnt=-1;}
        }sgt[maxn<<2], tag[maxn<<2];
    
        //正常建树
        void build(int p, int l, int r){
            tag[p].clear();
            if(l == r){
                sgt[p].cnt = 0;
                sgt[p].lc = sgt[p].rc = 0;
                sgt[p].ml = sgt[p].mr = l;
                return ;
            }
            int mid = l+r>>1;
            build(lch,l,mid);
            build(rch,mid+1,r);
            sgt[p] = sgt[lch]+sgt[rch];
        }
    
        void pushdown(int p){
            if(!~tag[p].cnt)return ;
            sgt[lch].lc = sgt[lch].rc = tag[p].cnt;
            sgt[rch].lc = sgt[rch].rc = tag[p].cnt;
            if(tag[p].cnt){
                sgt[lch].cnt = sgt[rch].cnt = 1;
                sgt[lch].ml = sgt[rch].ml = tag[p].ml;
                sgt[lch].mr = sgt[rch].mr = tag[p].mr;
                tag[lch] = tag[rch] = tag[p];
            }else{
                int mid = (tag[p].ml+tag[p].mr)>>1;
                sgt[lch].cnt = sgt[rch].cnt = 0;
                sgt[lch].ml = tag[p].ml, sgt[rch].ml = mid+1;
                sgt[lch].mr = mid, sgt[rch].mr = tag[p].mr;
                tag[lch] = tag[rch] = tag[p];
                tag[lch].mr = mid, tag[rch].ml = mid+1;
            }
            tag[p].clear();
        }
        //将区间[L,R]的颜色改为c.
        void update(int p, int l, int r, int L, int R, int c){
            if(L<=l && r<=R){
                sgt[p].lc = sgt[p].rc = c;
                tag[p].cnt = c;
                if(c){
                    sgt[p].cnt = 1;
                    sgt[p].ml = L, sgt[p].mr = R;
                    tag[p].ml = L, tag[p].mr = R;
                }else{
                    sgt[p].cnt = 0;
                    sgt[p].ml = l, sgt[p].mr = r;
                    tag[p].ml = l, tag[p].mr = r;
                }
                return ;
            }
            pushdown(p);
            int mid = l+r>>1;
            if(L<=mid)update(lch,l,mid,L,R,c);
            if(R>mid)update(rch,mid+1,r,L,R,c);
            sgt[p] = sgt[lch]+sgt[rch];
        }
        //查询[L,R]内这段区间的五个信息
        node query(int p, int l, int r, int L, int R){
            if(L<=l && r<=R)return sgt[p];
            pushdown(p);
            int mid = l+r>>1;
            if(L>mid)return query(rch,mid+1,r,L,R);
            if(R<=mid)return query(lch,l,mid,L,R);
            return query(lch,l,mid,L,R)+query(rch,mid+1,r,L,R);
        }
    }sgt;
    
    int main(){
        int n;  scanf("%d",&n);
        sgt.build(1,1,100000);
        for(int i = 1; i <= n; i++){
            char op;  cin>>op;
            if(op == 'A'){
                int l, r;  scanf("%d%d",&l,&r);
                SegmentTree::node t = sgt.query(1,1,100000,l,r);
                printf("%d
    ",t.cnt);
                sgt.update(1,1,100000,t.ml,t.mr,0);
                sgt.update(1,1,100000,l,r,i);
            }else{
                printf("%d
    ",sgt.query(1,1,100000,1,100000).cnt);
            }
        }
        return 0;
    }
  • 相关阅读:
    SqlServer2005自动备份
    在Win7下运行使用BDE的程序
    Hibernate连接SqlServer时的小问题
    使用Delphi在SqlServer中对日期的设置
    Flex中连接J2ee的一个小问题
    np使用创建图像 霍夫圆检测 video操作,显示canny边缘
    Web.config的配置
    SQL 进制间如何转换
    jQuery 设置和获取HTML,文本和值
    通过LINQ to XML生成 XML
  • 原文地址:https://www.cnblogs.com/gwj1314/p/10200103.html
Copyright © 2011-2022 走看看