【数据结构+线段树】连续型/离散型线段树
来源:互联网 发布:双界面软件手机 编辑:程序博客网 时间:2024/05/16 10:31
背景
在线段树的通常用法中,线段树的节点是有2种不同的意义的,
一种是离散型的:一个节点虽然描述的是一个区间[3, 9],但是实际上这样一个区间是{3, 4, 5, 6, 7, 8, 9}这样的意义。
而另一种就是连续型的:一个节点如果描述的是一个区间[3, 9],它就确确实实描述的是在数轴上从3这个标记到9这个标记的这一段。
这两种不同的意义有什么区别呢?
有这样的几个区别:
1.叶子节点:在离散型中,叶子节点是[i, i],而连续性中是[i, i + 1];
2.分解区间:在离散型中,一段区间是分解成为[l, m], [m + 1, r],而在连续型中,是分解成为[l, m], [m, r];3.其他所有类似的判定问题。
题目
小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 104 100 21 65 93 4
5
解法
区间离散化+连续型线段树
代码
#include <iostream>#include <string.h>#include <map>#include <set>#include <vector>using namespace std;int tree[1000000];void down(int l, int r, int idx){ if(tree[idx] && l<r){ tree[idx*2+1] = tree[idx*2+2] = tree[idx]; tree[idx] = 0;//@error: lost this }}void _set(int l, int r, int idx, int a, int b, int d){ if(a<=l && b>=r) { tree[idx] = d; return; } int mid = (l+r)/2; down(l, r, idx); if(a>=mid) _set(mid, r, idx*2+2, a, b, d); else if(b<=mid) _set(l, mid, idx*2+1, a, b, d); else{ _set(mid, r, idx*2+2, mid, b, d); // b > mid _set(l, mid, idx*2+1, a, mid, d); // a < mid }}int get(int l, int r, int idx, int a){ while(!tree[idx] && l+1<r){ int mid = (l+r)/2; if(a>=mid) l = mid , idx = idx*2 + 2; else r = mid, idx = idx*2 + 1;// a + 1 <= mid } return tree[idx];}int main(){ int n, l; cin>>n>>l; memset(tree, 0, sizeof(tree)); set<int> ss; vector<pair<int, int> > pp; for(int i=1; i<=n; i++){ int a, b; cin>>a>>b; ss.insert(a); ss.insert(b); pp.push_back(pair<int, int>(a, b)); } map<int, int> mm; int i = 0; for(set<int>::iterator it = ss.begin(); it!= ss.end(); it++){ mm[*it] = i++; } int N = ss.size(); for(int i=1; i<=n; i++){ pair<int, int> &p = pp[i-1]; _set(0, N-1, 0, mm[p.first], mm[p.second], i); } set<int> res; for(int i=0; i < N - 1; i++){//@attention: i<N-1, the last point int j = get(0, N-1, 0, i); // [i, i+1] if(j) res.insert(j); } cout<<res.size()<<endl; return 0;}
- 【数据结构+线段树】连续型/离散型线段树
- 线段树3(离散化,连续区间)
- 线段树+离散化
- 离散化 + 线段树
- poj2528 离散线段树
- 线段树离散化
- 线段树离散化
- hihoCoder 1079 : 离散化(线段树之连续区间+离散化) 经典题型
- poj 2528 Mayor's posters(数据结构:线段树+离散化)
- 【线段树+离散化】Uestc-数据结构专题训练【B】
- POJ_2528 线段树+离散化
- HDU3577 离散化+线段树
- poj2528 线段树+离散化
- poj2528线段树+离散化
- hdu4325线段树+离散化
- POJ2528 离散化线段树
- 【线段树+离散化】Cover
- poj2482 离散化+线段树
- 关于抱怨
- JAVA程序设计(18.1)----- 1多线程轮流打印 线程调度 线程池 synchronized wait notify 内部类
- 【翻译】Intel要回答的5个问题
- 如何让自己静下来
- 接下来的计划目标是什么呢?
- 【数据结构+线段树】连续型/离散型线段树
- 的撒打算;打卡上;打卡上;打开;阿什利看到;拉SD卡
- varnish
- 算法分类
- Storm杂谈之Topology的启动过程(一)
- Codeforces 487B. Strip(求区间最值+线段树上的dp)
- 左键获取当前鼠标选中的文件的路径
- Android中error inflating class fragment
- 给我任何污染环境危机而