NSOJ 4621 posters (离散化+线段树)

posters

时间限制: 1000ms

内存限制: 128000KB

64位整型:      Java 类名:

上一题

提交 运行结果 统计 讨论版

下一题

题目描述

The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules:
• Every candidate can place exactly one poster on the wall.
• All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown).
• The wall is divided into segments and the width of each segment is one byte.
• Each poster must completely cover a contiguous number of wall segments.

They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections.
Your task is to find the number of visible posters when all the posters are placed given the information about posters‘ size, their place and order of placement on the electoral wall. 

输入

The first line of input contains a number c giving the number of cases that follow. The first line of data for a single case contains number 1 <= n <= 10000. The subsequent n lines describe the posters in the order in which they were placed. The i-th line among the n lines contains two integer numbers li and ri which are the number of the wall segment occupied by the left end and the right end of the i-th poster, respectively. We know that for each 1 <= i <= n, 1 <= li <= ri <= 10000000. After the i-th poster is placed, it entirely covers all wall segments numbered li, li+1 ,... , ri.

输出

For each input data set print the number of visible posters after all the posters are placed.

The picture below illustrates the case of the sample input.
http://acm.pku.edu.cn/JudgeOnline/images/2528_1.jpg

样例输入

1
5
1 4
2 6
8 10
3 4
7 10

样例输出

4

来源

NYOJ

题意:

   在一面长墙上贴n张海报,第 i 张海报可以从 li 贴到 ri ,海报高低都相等(可以理解为一维模型),按照给出的方法依次粘贴,问最终还能看见海报有几张。

分析:

   起始点与终止点取值范围(1 <= i <= n, 1 <= li <= ri <= 10000000)  然而 我们用到的只有(1 <= n <= 10000)个,只用到了(1/1000)*2的点,要保存整个状态,开10000000的整形数组果断超内存,运用离散化思想用20000的整形数组便能保存整个状态。

   如果按照一般的方法,你在一张海报区域对应范围内 逐个赋值保存状态,离散化后最坏的情况依然为2*c*n2果断超时,这时就要用到线段树来优化了,线段树用到二分思想故最坏情况为2*c*nlogn,(c的范围没有给出,索性考虑在内,但c应该也不会太大)。


 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>    //映射->离散化
 4 #include <set>  //自动去重
 5 using namespace std;
 6 #define MAXN 10005
 7 map <int,int> M;
 8 struct node{
 9     int left;
10     int right;
11     int index;
12     node(): left(0), right(0), index(0) {}
13 } Tree[MAXN * 4], input[MAXN];
14
15 int point[MAXN * 2], sum;
16 set <int> visible;
17
18 void BuildTree(int root, int left, int right){ //建立线段树
19     Tree[root].left = left;
20     Tree[root].right = right;
21     Tree[root].index = -1;
22     if (left + 1 < right){
23         int mid = (left + right) / 2;
24         BuildTree(root * 2, left, mid);
25         BuildTree(root * 2 + 1, mid, right);
26     }
27 }
28
29 void UpdateTree(int k, int a, int b, int index){
30     if (Tree[k].left == a && Tree[k].right == b){
31         Tree[k].index = index;
32         return;
33     }
34     if (Tree[k].index != -1){
35         Tree[2 * k].index = Tree[2 * k + 1].index = Tree[k].index;
36         Tree[k].index = -1;
37     }
38     int mid = (Tree[k].left + Tree[k].right) / 2;
39     if (b <= mid)
40         UpdateTree(2 * k, a, b, index);
41     else if (a >= mid)
42         UpdateTree(2 * k + 1, a, b, index);
43     else {
44         UpdateTree(2 * k, a, Tree[2 * k].right, index);
45         UpdateTree(2 * k + 1, Tree[2 * k + 1].left, b, index);
46     }
47 }
48 void SearchTree(int k) { //便历
49     if (Tree[k].index != -1)
50         visible.insert(Tree[k].index);
51     else if (Tree[k].right > Tree[k].left + 1) {
52         SearchTree(2 * k);
53         SearchTree(2 * k + 1);
54     }
55 }
56 int main() {
57     int c, n;
58     cin >> c;
59     while (c--) {
60         cin >> n;
61         sum = 0;
62         for (int i = 0; i < n; i++) {
63             cin >> input[i].left >> input[i].right;
64             input[i].left--;
65             point[sum++] = input[i].left;
66             point[sum++] = input[i].right;
67         }
68         sort(point, point + sum);
69         sum = unique(point, point + sum) - point;//去重后共sum个点
70         M.clear();
71         for(int i=0;i<sum;i++){
72             M[point[i]]=i; //映射
73         }
74         BuildTree(1, 0, sum - 1);
75         for (int i = 0; i < n; i++) {
76             UpdateTree(1, M[input[i].left], M[input[i].right], i);
77         }
78         visible.clear();
79         SearchTree(1);
80         cout << visible.size() << endl;
81     }
82     return 0;
83 }
时间: 2024-10-20 09:17:43

NSOJ 4621 posters (离散化+线段树)的相关文章

Mayor&#39;s posters(离散化线段树)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 54067   Accepted: 15713 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ 2528 Mayor&#39;s posters(离散化线段树)

Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for

POJ 2528 Mayor&amp;#39;s posters 离散化+线段树

题目大意:给出一些海报和贴在墙上的区间.问这些海报依照顺序贴完之后,最后能后看到多少种海报. 思路:区间的范围太大,然而最多仅仅会有10000张海报,所以要离散化. 之后用线段树随便搞搞就能过. 关键是离散化的方法,这个题我时隔半年才A掉,之前一直就TTT,我还以为是线段树写挂了. 当我觉得我自己的水平这样的水线段树已经基本写不挂的时候又写了这个题,竟然还是T. 后来我对照别人的代码,才发现是我的离散化写渣了. 以下附AC代码(79ms),这个离散化写的比較优雅.时间也非常快,以后就这么写了.

【POJ】2528 Mayor&#39;s posters ——离散化+线段树

Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city

POJ 2528 Mayor&#39;s posters(离散化 线段树)

题意  在墙上贴n张海报  输入每张海报的的左右端点坐标  问最后可以看到多少张海报  能看到一点也是能看到 先把线段树初始化为0 输入一张海报  就把那个区间变成这张海报的序号  最后判断墙上有多少个不同的序号就行了 但是海报坐标的端点值高达10000000  直接用线段树会超时   但是注意到海报最多只有10000张  也就是最多有20000个不同的坐标  于是可以利用离散化的知识   把所有坐标排序 注意所有右端点坐标+1也要加入排序(注意1,10 ; 1,3;  7,10这种情况  如果

POJ - 2528 - Mayor&#39;s posters 【线段树+离散化+补点】

http://poj.org/problem?id=2528 #include <cstdio> #include <iostream> #include <set> #include <cstring> #include <string> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 32768 + 5; in

poj 2528 Mayor&#39;s posters【离散化+线段树】

题目:poj 2528 Mayor's posters 题意:给一个长度非常长的墙上贴长度为ai的海报,由于有的会覆盖掉,求最后能看见的海报个数. 分析:题目和POJ2777 一模一样,方法也一样,只不过这个要离散化,其次要数组开大一点.至少2倍. 离散化的时候用了C++的 pair 类,还是比较好用的. 代码: #include <iostream> #include <algorithm> #include <utility> #include <cstrin

南阳理工 题目9:posters(离散化+线段树)

posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally deci

【POJ】 2528 - Mayor&#39;s posters 【线段树+离散化】

题目: Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 47228   Accepted: 13719 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral

POJ 2528 Mayor&#39;s posters (离散化 + 线段树)

强烈不推荐在POJ做这道题!!! 强烈不推荐在POJ做这道题!!! 强烈不推荐在POJ做这道题!!! 推荐去UVA 10587 或 SCU 2249 POJ的数据比较水且可能有错,一些本来错误的数据但可以水过,以及在UVA与SCU同样题目都能AC的程序在POJ莫名WA了. 建议写完程序后跑下这组数据: 1 3 1 10 1 3 6 10 好多题解的答案是2,但答案明显是3,这是因为每个数字其实表示的是一个单位长度,并非一个点 , 这就会导致像这样的区间: 1-10 1-4 5-10 1-10 1