zoukankan      html  css  js  c++  java
  • POJ 2528 Mayor's posters 线段树 离散化

      题目链接: http://poj.org/problem?id=2528

      题目描述: 在一个长度为maxn 的墙上贴海报, 海报按先后给出的顺序进行粘贴, 可以相互覆盖, 问最后可以露出几个海报(maxn <= 1e7)

      解题思路:一开始读错题了.....以为是覆盖的最多数.....如果是这样的话就直接统计最大值就可以了。 后来读明白题, 但是1e7数组又开不下, 所以得离散化, 但是这里又遇到一个问题

          给出下面两个简单的例子应该能体现普通离散化的缺陷:    
          例子一:1-10 1-4 5-10
          例子二:1-10 1-4 6-10
          普通离散化后都变成了[1,4][1,2][3,4]
          线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被完全覆盖掉了呢?
          例子一是完全被覆盖掉了,而例子二没有被覆盖                             转自http://blog.csdn.net/metalseed/article/details/8039326

        解决方法是在两个相差不为1的节点之后在插入一个值, 再做线段树, 由于这里只关心不同布段出现的次数, 所以不需要pushup函数, 直接一个全局变量配合着hash表就可以

        代码中有部分注释

      代码: 

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <map>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    typedef long long LL;
    using namespace std;
    int cases;
    const int maxn = 1e5+100;
    bool hash1[maxn];
    int li[maxn];
    int ri[maxn];
    int X[maxn*3];
    int col[maxn<<4];
    int cnt;
    
    void PushDown( int rt ) {
        if( col[rt] != -1 ) {
            col[rt<<1] = col[rt<<1|1] = col[rt];
            col[rt] = -1;
        }
    }
    
    void update( 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 ) update( L, R, c, lson );
        if( m < R ) update( L, R, c, rson );
    }
    void query( int l, int r, int rt ) {
        if( col[rt] != -1 ) {
            if( !hash1[col[rt]] ) cnt++;
            hash1[col[rt]] = true;
            return;
        }
        if( l == r ) return;
        int m = (l + r) >> 1;
        query( lson );
        query( rson );
    }
    int Bin( int key, int n, int X[] ) {   // Bin to find the value
        int l = 0;
        int r = n-1;
        while( l <= r ) {
            int m = (l + r) >> 1;
            if( X[m] == key ) return m;
            if( X[m] < key ) l = m + 1;
            else r = m-1;
        }
        return -1;
    }
    int main() {
        int t, n;
        scanf( "%d", &t );
        while( t-- ) {
            scanf( "%d", &n );
            int nn = 0;
            for( int i = 0; i < n; i++ ) {
                scanf( "%d%d", li+i, ri+i );
                X[nn++] = li[i];
                X[nn++] = ri[i];
            }
            sort( X, X+nn );
            int m = 1;
            for( int i = 1; i < nn; i++ ) { // unique
                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] + 1; // deal with the drawback
            }
            sort( X, X+m );
            memset(col, -1, sizeof(col));
            for( int i = 0; i < n; i++ ) {
                int l = Bin(li[i], m, X);
                int r = Bin(ri[i], m, X);
                update( l, r, i, 0, m, 1 );
            }
            cnt = 0;
            memset( hash1, false, sizeof( hash1) );
            query(0, m, 1);
            printf( "%d
    ", cnt );
        }
        return 0;
    }
    View Code

      思考: 自己第一次做不是裸的线段树, 还是有好多好多不熟练的地方, 决定按照之前转载的那篇博客先把那里的题目刷干净, 在自己去找题做, 线段树是个硬骨头, 不好啃, 需要一些耐心, 但是只要学明白线段树, 收益无穷。 

      今晚儿再做一道DP。。。。。。

  • 相关阅读:
    Ubuntu 18.04.4 系统优化
    Ubuntu 18.04.4 LTS 更换国内系统源
    django 数据库迁移
    django2.0解决跨域问题
    python requests get请求传参
    python 常用排序方法
    python 电脑说话
    centos6.x配置虚拟主机名及域名hosts
    php 合并,拆分,追加,查找,删除数组教程
    PHP统计在线用户数量
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7300511.html
Copyright © 2011-2022 走看看