hihocoder #1079 : 离散化-线段树应用

#1079 : 离散化

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~

这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住。看到这个场景,小Hi便产生了这样的一个疑问——最后到底能有几张海报还能被看见呢?

于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作长度为L的一段区间,且有N张海报按照顺序依次贴在了宣传栏上,其中第i张海报贴住的范围可以用一段区间[a_i, b_i]表示,其中a_i, b_i均为属于[0, L]的整数,而一张海报能被看到当且仅当存在长度大于0的一部分没有被后来贴的海报所遮挡住。那么问题就来了:究竟有几张海报能被看到呢?

提示一:正确的认识信息量

提示二:小Hi大讲堂之线段树的节点意义

输入

每个测试点(输入文件)有且仅有一组测试数据。

每组测试数据的第1行为两个整数N和L,分别表示总共贴上的海报数量和宣传栏的宽度。

每组测试数据的第2-N+1行,按照贴上去的先后顺序,每行描述一张海报,其中第i+1行为两个整数a_i, b_i,表示第i张海报所贴的区间为[a_i, b_i]。

对于100%的数据,满足N<=10^5,L<=10^9,0<=a_i<b_i<=L。

输出

对于每组测试数据,输出一个整数Ans,表示总共有多少张海报能被看到。

样例输入
5 10
4 10
0 2
1 6
5 9
3 4
样例输出
5

注意点

连续型线段树一段区间是分解成为[l, m], [m + 1, r]
#include <iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<set>
#include<map>
using namespace std;
const int max_N = 100000;
int a[max_N+1], b[max_N+1];
int value[max_N<<2] = {0};
int N, L, left_bound = 1, right_bound = 0;
void read_and_compress(){
    set<int> s;
    map<int, int> m;
    scanf("%d %d", &N, &L);
    for(int i = 1; i <= N; ++i){
        scanf("%d %d", &a[i], &b[i]);
        s.insert(a[i]);
        s.insert(b[i]);
    }
    right_bound = 0;
    for(set<int>::iterator it = s.begin(); it != s.end(); ++it){
        m[*it] = ++right_bound;
    }
    for(int i = 1; i <= N; ++i){
        a[i] = m[a[i]];
        b[i] = m[b[i]];
    }
}
void push_down(int value[], int idx){
    if(value[idx] > 0){
        value[idx<<1] = value[idx];
        value[(idx<<1)|1] = value[idx];
        value[idx] = 0;
    }
}
void update(int value[], int idx, int left, int right, int l, int r, int v){
    if(l >= r || r <= left || l >= right || left >= right) return;
    if(l <= left && right <= r){
        value[idx] = v;
    }else{
        push_down(value, idx);
        int mid = (left + right) >> 1;
        if(l < mid) update(value, idx<<1, left, mid, l, r, v);
        if(mid < r) update(value, (idx<<1)|1, mid, right, l, r, v);
    }
}
void query(int value[], int idx, int left, int right, int l, int r, set<int> &s){
    if(l >= r || left >= right || r <= left || l >= right) return;
    if(value[idx] > 0){
        s.insert(value[idx]);
    }else if(left + 1 < right){
        int mid = (left + right) >> 1;
        query(value, idx<<1, left, mid, l, r, s);
        query(value, (idx<<1)|1, mid, right, l, r, s);
    }
}
void print_tree(int[], int, int, int);
int main(){
    read_and_compress();
    for(int i = 1; i <= N; ++i){
        update(value, 1, left_bound, right_bound, a[i], b[i], i);
    }
    set<int> s;
    query(value, 1, left_bound, right_bound, left_bound, right_bound, s);
    int ans = s.size();
    printf("%d\n", ans);
    return 0;
}
时间: 2024-10-24 04:31:35

hihocoder #1079 : 离散化-线段树应用的相关文章

hihoCoder #1079 : 离散化 (线段树,数据离散化)

题意:有一块宣传栏,高一定,给出长度,再给出多张海报的张贴位置,问还能见到几张海报(哪怕有一点被看到)?假设海报的高于宣传栏同高. 思路:问题转成“给出x轴上长为L的一条线段,再用n条线段进行覆盖上去,最后还能看到及条线”.长度是0~L,即长度是L,进行离散化的时候,应该用1~L,每个数字表示一个单位长.还有就是按照提示所给的信息实现即可.步骤如下: (1)保存n个数据,做成pair,并将所有出现过的数字在另外找地方排序,去掉重复的,再将数据紧缩化处理,那么大小在1~max.再将紧缩化的数据与原

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

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

POJ 2299 离散化线段树

点击打开链接 Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 40827   Accepted: 14752 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by

南阳理工 题目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

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

bnu36905 Nested Segments 离散化+线段树

bnu36905 Nested Segments 离散化+线段树区间更新 也可以用离散化+set(或双向链表) #include <cstdio> #include <ctime> #include <cstdlib> #include <cstring> #include <queue> #include <string> #include <set> #include <stack> #include &l

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

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

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