zoukankan      html  css  js  c++  java
  • poj 2528 线段树+离散化

    转自:http://blog.csdn.net/non_cease/article/details/7383736

    题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报

    解法:离散化,如下面的例子(题目的样例),因为单位1是一个单位长度,将下面的

          1   2   3   4  6   7   8   10

         —  —  —  —  —  —  —  —

          1   2   3   4  5   6   7   8

    离散化  X[1] = 1; X[2] = 2; X[3] = 3; X[4] = 4; X[5] = 6; X[7] = 8; X[8] = 10

    于是将一个很大的区间映射到一个较小的区间之中了,然后再对每一张海报依次更新在宽度为1~8的墙上(用线段树),最后统计不同颜色的段数。

    但是只是这样简单的离散化是错误的,

    如三张海报为:1~10 1~4 6~10

    离散化时 X[ 1 ] = 1, X[ 2 ] = 4, X[ 3 ] = 6, X[ 4 ] = 10
    第一张海报时:墙的1~4被染为1;
    第二张海报时:墙的1~2被染为2,3~4仍为1;
    第三张海报时:墙的3~4被染为3,1~2仍为2。
    最终,第一张海报就显示被完全覆盖了,于是输出2,但实际上明显不是这样,正确输出为3。

    新的离散方法为:在相差大于1的数间加一个数,例如在上面1 4 6 10中间加5(算法中实际上1,4之间,6,10之间都新增了数的)

    X[ 1 ] = 1, X[ 2 ] = 4, X[ 3 ] = 5, X[ 4 ] = 6, X[ 5 ] = 10

    这样之后,第一次是1~5被染成1;第二次1~2被染成2;第三次4~5被染成3

    最终,1~2为2,3为1,4~5为3,于是输出正确结果3。

    Sample Input
    1
    5
    1 4
    2 6
    8 10
    3 4
    7 10
    Sample Output
    4

    有点坑,明天再看一遍

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 #define lson l , m , rt << 1
     6 #define rson m + 1 , r , rt << 1 | 1
     7 
     8 const int maxn = 11111;
     9 bool hash[maxn];
    10 int li[maxn] , ri[maxn];
    11 int X[maxn*3];
    12 int col[maxn<<4];
    13 int cnt;
    14 
    15 void PushDown(int rt) {
    16     if (col[rt] != -1) {
    17         col[rt<<1] = col[rt<<1|1] = col[rt];
    18         col[rt] = -1;
    19     }
    20 }
    21 void update(int L,int R,int c,int l,int r,int rt) {
    22     if (L <= l && r <= R) {
    23         col[rt] = c;
    24         return ;
    25     }
    26     PushDown(rt);
    27     int m = (l + r) >> 1;
    28     if (L <= m) update(L , R , c , lson);
    29     if (m < R) update(L , R , c , rson);
    30 }
    31 void query(int l,int r,int rt) {
    32     if (col[rt] != -1){
    33         if (!hash[col[rt]]) cnt++;
    34         hash[ col[rt] ] = true;
    35         return ;
    36     }
    37     if (l == r) return ;
    38     int m = (l + r) >> 1;
    39     query(lson);
    40     query(rson);
    41 }
    42 int Bin(int key,int n,int X[]) {
    43     int l = 0 , r = n - 1;
    44     while (l <= r) {
    45         int m = (l + r) >> 1;
    46         if (X[m] == key) return m;
    47         if (X[m] < key) l = m + 1;
    48         else r = m - 1;
    49     }
    50     return -1;
    51 }
    52 int main() {
    53     int T , n;
    54     //freopen("1.in","r",stdin);
    55     scanf("%d",&T);
    56     int i;
    57     while (T --) {
    58         scanf("%d",&n);
    59         int nn = 0;
    60         for (int i = 0 ; i < n ; i ++) {
    61             scanf("%d%d",&li[i] , &ri[i]);
    62             X[nn++] = li[i];
    63             X[nn++] = ri[i];
    64         }
    65         sort(X , X + nn);
    66         /*for(i=0;i<nn;i++)   printf("%d ",X[i]);
    67         printf("
    ");*/
    68         int m = 1;
    69         for (int i = 1 ; i < nn; i ++) {
    70             if (X[i] != X[i-1]) X[m ++] = X[i];
    71         }
    72         for (int i = m - 1 ; i > 0 ; i --) {
    73             if (X[i] != X[i-1] + 1) X[m ++] = X[i-1] + 1;
    74         }
    75         sort(X , X + m);
    76         /*for(i=0;i<m;i++)    printf("%d ",X[i]);
    77         printf("
    ");*/
    78         memset(col , -1 , sizeof(col));
    79         for (int i = 0 ; i < n ; i ++) {
    80             int l = Bin(li[i] , m , X);
    81             int r = Bin(ri[i] , m , X);
    82             update(l , r , i , 0 , m , 1);
    83         }
    84         cnt = 0;
    85         memset(hash , false , sizeof(hash));
    86         query(0 , m , 1);
    87         printf("%d
    ",cnt);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    Linux:password 与passphrase
    QT设置openCV头文件和链接动态库路径
    matlab对图像加入噪声的方法
    RGB到HSV的彩色空间变化 Matlab
    QImage与IplImage之间的转换
    iframe自适应高度(简单经典)兼容ie6ie9 ,firefox,opera,chrome
    转载:关于生成并发唯一性流水号的解决方案
    EXCEL表格纵横转换
    rdlc打印时多出空白页面(reportviewer)
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4281760.html
Copyright © 2011-2022 走看看