zoukankan      html  css  js  c++  java
  • [SHOI2009]会场预约 [线段树 染色][STL set]

    P2161 [SHOI2009]会场预约

    这个题我xio到了好多东西QAQ

    线段树 染色

    可以看这个大佬的题解 瓜打了一会儿 发现自己完全不会QAQ 然后学到了线段树染色这一方法

    col数组表示这段区间的颜色是否相同 0为不同 1为相同

    del记录这种颜色是否被删掉 然后在后面的操作中搞它!

    tag记录的区间颜色

    QAQ发现我基础真的不牢 啥都没搞清楚:下传操作的进行,是因为当前区间不完全在修改区间范围内((否则就直接changechange并且returnreturn了)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define Max(x,y) (x)>(y)?(x):(y)
    #define Min(x,y) (x)>(y)?(y):(x)
    #define lson o<<1
    #define rson o<<1|1
    #define ll long long
    #define rg register
    const int N=200000+5,M=10000+5,inf=0x3f3f3f3f,P=99999997;
    int n,cnt=0,tot=0,era,s=inf,t=0;
    int sum[N<<1],tag[N<<1],col[N<<1],del[N<<1];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    struct node{
        char a[3];
        int x,y;
    }ask[N];
    
    void pushdown(int o,int l,int r){
        col[o]=0;//下传时 这个区间显然不同色 
        if(!tag[o]) return;
        else tag[lson]=tag[rson]=tag[o],tag[o]=0;
    }
    
    void change(int o,int x,int y,int k){
        if(col[o]==1){//为同一个颜色
            if(!del[tag[o]]&&tag[o]) --cnt,++era;
            //该种颜色未被删掉
            del[tag[o]]=1,tag[o]=k;return;//记录为删掉 并改变颜色 
        }
        int mid=(x+y)>>1;
        change(lson,x,mid,k),change(rson,mid+1,y,k);
        tag[o]=k,col[o]=1;//覆盖 
    }
    
    void buildtree(int o,int l,int r){
        col[o]=1;//初始都为一个未被覆盖的颜色 
        if(l<r){
            int mid=(l+r)>>1;
            buildtree(lson,l,mid),buildtree(rson,mid+1,r);
        }
    }
    
    void update(int o,int l,int r,int x,int y,int k){
        if(r<x||l>y) return;
        if(x<=l&&r<=y){
            change(o,x,y,k);return;
        }
        pushdown(o,l,r);//进行下传操作 因为当前区间不完全在修改区间内 
        int mid=(l+r)>>1;
        update(lson,l,mid,x,y,k),update(rson,mid+1,r,x,y,k);
    }
    
    
    int main(){
        freopen("in.txt","r",stdin);
        rd(n);
        for(int i=1,x,y;i<=n;++i){
            scanf("%s",ask[i].a);
            if(ask[i].a[0]=='A') rd(x),rd(y),ask[i].x=x,ask[i].y=y,s=Min(s,x),t=Max(t,y);
        }
        buildtree(1,s,t);
        for(int i=1;i<=n;++i)
        if(ask[i].a[0]=='A'){
            ++cnt,era=0;
            update(1,s,t,ask[i].x,ask[i].y,++tot);
            printf("%d
    ",era);
        }else printf("%d
    ",cnt);
        return 0;
    }

    STL set

    洛谷上一个大佬的做法

    用一个结构体来储存预约的方案 我们知道set里不存在相同的key 可以通过s.find()来寻找

    通过结构体重载运算符 重载为:bool operator <(const book &b)const{return r<b.l;}

    这样a<b即为a完全在b左边 b<a即为a完全在b右边 a==b即为a和b有相交的区间

    再来存一下set的用法

    begin()       返回set容器的第一个元素
    end()        返回set容器的最后一个元素
    clear()       删除set容器中的所有的元素
    empty()       判断set容器是否为空
    max_size()      返回set容器可能包含的元素最大个数
    size()        返回当前set容器中的元素个数
    rbegin        返回的值和end()相同
    rend()        返回的值和rbegin()相同
    erase(iterator)   删除定位器iterator指向的值
    erase(first,second) 删除定位器first和second之间的值
    erase(key_value)  删除键值key_value的值
    find()        返回给定值值得定位器,如果没找到则返回end()。
    set<int>::iterator iter;

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) (x)>(y)?(x):(y)
    #define Min(x,y) (x)>(y)?(y):(x)
    #define ll long long
    #define rg registerint n;
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    struct book{
        int l,r;
        bool operator <(const book &b)const{return r<b.l;}
    };
    set<book>s;
    int main(){
        freopen("in.txt","r",stdin);
        rd(n);
        for(int i=1;i<=n;++i){
            char op[2];
            scanf("%s",op);
            if(op[0]=='A'){
                int l,r,era=0;rd(l),rd(r);
                book x=(book){l,r};
                set<book>::iterator iter;
                iter=s.find(x);
                while(iter!=s.end()){
                    ++era;s.erase(iter);
                    iter=s.find(x);
                }
                printf("%d
    ",era);
                s.insert(x);
            }
            else printf("%d
    ",s.size());
        }
        return 0;
    }
  • 相关阅读:
    loadrunner关联及web_reg_save_param方法浅析
    zookeeper安装教程(zookeeper3.4.5为例)
    centos6.5 常用命令
    centos修改主机名的正确方法
    ZooKeeper的安装与部署
    这可能是把ZooKeeper概念讲的最清楚的一篇文章
    Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法
    SQLite -分离数据库
    大忙人的jdk8,比出生晚了好几个激情的夏天
    查询优化基础知识
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11193738.html
Copyright © 2011-2022 走看看