码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-07 20:19:29      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:

#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;
}

 

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

标签:

原文地址:http://www.cnblogs.com/poweryong/p/4485786.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!