#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的一部分没有被后来贴的海报所遮挡住。那么问题就来了:究竟有几张海报能被看到呢?
输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第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