• Poj 2528 Mayor's posters (线段树+离散化)


    题目连接:

      http://poj.org/problem?id=2528

    题目大意:

      有10000000块瓷砖,n张海报需要贴在墙上,每张海报所占的宽度和瓷砖宽度一样,长度是瓷砖长度的整数倍,问按照所给海报顺序向瓷砖上贴海报,最后有几张海报是可见的?

    解题思路:

      因为瓷砖块数和海报张数多,首选线段树,如果按照常规的建树方式,把瓷砖当做数的节点,肯定会MTL.........

    所以我们可以用海报的起点和终点当做树的节点,这样树的节点才有20000个,但是这样建树的话,求海报覆盖了那些节点会很复杂,所以我们对每个海报所覆盖的区间也对应建立了一个节点,这样的话线段树有39999个节点。

    分析完咯,然后就是建树,还有就是贴海报的时候要倒着贴,这样的话插入海报的时候直接可以判断出来此海报是不是可见。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn = 10005;
     7 struct poster
     8 {
     9     int l, r;
    10 };
    11 struct node
    12 {
    13     int l, r;
    14     bool sta;
    15     int Mid()
    16     {
    17         return ( l + r ) / 2;
    18     }
    19 };
    20 node tree[16*maxn];
    21 poster pos[maxn];
    22 int hash[maxn*1000], x[maxn*2];
    23 
    24 void Build (int root, int l, int r)
    25 {
    26     tree[root].l = l;
    27     tree[root].r = r;
    28     tree[root].sta = true;
    29     if (l == r)
    30         return ;
    31     Build (2*root+1, l, tree[root].Mid());
    32     Build (2*root+2, tree[root].Mid()+1, r);
    33 }
    34 
    35 int update (int root, int l, int r)
    36 {
    37     if (!tree[root].sta)
    38         return 0;
    39     if (tree[root].l == l && tree[root].r == r)
    40     {
    41         tree[root].sta = false;
    42         return 1;
    43     }
    44     int x;
    45     if (r <= tree[root].Mid())
    46         x = update (2*root+1, l, r);
    47     else if (tree[root].Mid() < l)
    48         x = update (2*root+2, l, r);
    49     else
    50     {
    51         int b1 = update (2*root+1, l, tree[root].Mid());
    52         int b2 = update (2*root+2, tree[root].Mid()+1, r);
    53         x = b1 || b2;
    54     }
    55     if (!tree[2*root+1].sta && !tree[2*root+2].sta)
    56         tree[root].sta = false;
    57         return x;
    58 }
    59 int main ()
    60 {
    61     int t;
    62     scanf ("%d", &t);
    63     while (t --)
    64     {
    65         int n, num = 0;
    66         scanf ("%d", &n);
    67         for (int i=0; i<n; i++)
    68         {
    69             scanf ("%d %d", &pos[i].l, &pos[i].r);
    70             x[num++] = pos[i].l;
    71             x[num++] = pos[i].r;
    72         }
    73         sort(x, x+num);
    74         num = unique(x, x+num) - x;
    75         memset (hash, 0, sizeof(hash));
    76         int nu = 0;
    77         for (int i=0; i<num; i++)
    78         {
    79             hash[x[i]] = nu;
    80             if (i < num - 1)
    81             {
    82                 if (x[i+1] - x[i] == 1)
    83                     nu ++;
    84                 else
    85                     nu += 2;
    86             }
    87         }
    88         Build(0, 0, nu);
    89         int sum = 0;
    90         for (int i=n-1; i>=0; i--)
    91             sum += update (0, hash[pos[i].l], hash[pos[i].r]);
    92                                 printf ("%d
    ", sum);
    93         }
    94                    return 0;
    95 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    MFC OnPaint()函数中最先调用CDialog::OnPaint()和最后调用CDialog::OnPaint()的巨大区别
    教你如何快速使用Github
    NET开发者部署React-Native
    分层架构
    微内核架构(Microkernel Architecture)
    ABP-N层架构
    MVC 应用免受 CSRF攻击
    Redis时延问题
    JS call与apply
    jQuery插件编写
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4625482.html
Copyright © 2020-2023  润新知