• POJ-2528 Mayor's posters (离散化, 线段树)


    题目传送门: POJ-2528

    题意就是在一个高度固定的墙面上贴高度相同宽度不同的海报,问贴到最后还能看到几张?本质上是线段树区间更新问题,但是要注意的是题中所给数据范围庞大,直接搞肯定会搞出问题,所以要离散化,而离散化的过程中要注意一个问题,比方说1-10,1-5,6-10,本来是可以三张海报都可以看见的,但是按照题意来看是看不到的,因为他是一个点代表一个单位长度(诡异>_<),解决的办法则是对于距离大于1的两相邻点,中间再插入一个点......

    代码如下,我用了vector,和用数组的相差大改50ms左右,如果时间不是特别紧的话,完全可以用vector,还可以借助STL来节省时间(懒???>_<)......

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    
    using namespace std;
    #define lson l, m, rt << 1
    #define rson m+1, r, rt << 1 | 1
    
    const int N = 20000 + 5;
    int col[N<<4], li[N], ri[N],Hash[N], cnt;
    vector<int> x;
    
    void PushDown(int rt){
        if(col[rt] != -1){
            col[rt<<1] = col[rt<<1|1] = col[rt];
            col[rt] = -1;
        }
    }
    
    void Updata(int L, int R, int c, int l, int r, int rt){
        if(L <= l && r <= R){
            col[rt] = c;
            return ;
        }
        PushDown(rt);
        int m = (l + r) >> 1;
        if(L <= m) Updata(L, R, c, lson);
        if(R > m) Updata(L, R, c, rson);
    }
    
    void Query(int l,int r,int rt) {
        if (col[rt] != -1) {
            if (!Hash[col[rt]]) cnt ++;
            Hash[col[rt]] = true;
            return ;
        }
        if (l == r) return ;
        int m = (l + r) >> 1;
        Query(lson);
        Query(rson);
    }
    
    int Tran(int pos){
        return distance(x.begin(), lower_bound(x.begin(), x.end(), pos)); //这个地方要注意, x.begin()要放前面, 不然出来的都是负值
    }
    
    int Disc(vector<int> &x){                        //vector离散化
        sort(x.begin(), x.end());
        x.erase(unique(x.begin(), x.end()), x.end());
        for(int i = x.size() - 1; i > 0; i--)
            if(x[i] != x[i-1] + 1) x.push_back(x[i]+1);
        sort(x.begin(), x.end());
        return x.size();
    }
    
    /**
    int Disc(int cur, int X[]){                   //数组离散化
        sort(X, X + cur);
        int m = 1;
        for(int i = 1; i < cur; i++){
            if(X[i]!=X[i-1]) X[m++] = X[i];
        }
        for(int i = m-1; i > 0; i--){
            if(X[i] != X[i-1] + 1) X[m++] = X[i] + 1;
        }
        sort(X, X + m);
        return m;
    }
    */
    
    void Init_work(){
        memset(col, -1, sizeof(col));
        memset(Hash, false, sizeof(Hash));
        cnt = 0;
    }
    
    int main(){
        int T,n;
        scanf("%d", &T);
        while(T--){
            Init_work();
            scanf("%d", &n);
            for(int i = 0; i < n; i++){
                scanf("%d %d", &li[i], &ri[i]);
                x.push_back(li[i]);
                x.push_back(ri[i]);
            }
            int m = Disc( x );
    
            for(int i = 0; i < n; i++){
                Updata(Tran(li[i]), Tran(ri[i]), i, 0, m, 1);
            }
    
            Query(0, m, 1);
            printf("%d
    ",cnt);
        }
    }


  • 相关阅读:
    使用visio 2007对现有的数据库进行反向工程
    GOOGLE地图坐标拾取方法、GOOGLE地图获取坐标方法
    Visio 2007中进行数据库建模时如何显示字段类型以及概念名称
    WCF把书读薄(4)——事务编程与可靠会话
    WCF把书读薄(3)——数据契约、消息契约与错误契约
    WCF把书读薄(2)——消息交换、服务实例、会话与并发
    Backbone.js developer 武汉 年薪8w-10w
    Java面试
    从pb文件中恢复计算图并在tensorboard中展示
    Ubuntu下解决u盘变成只读模式
  • 原文地址:https://www.cnblogs.com/Pretty9/p/7384038.html
Copyright © 2020-2023  润新知