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\n", sum);
93         }
94                    return 0;
95 }

 

你可能感兴趣的:(post)