POJ2528Mayor's posters(离散化 + 线段树)
2016-03-02 20:26
337 查看
题目链接:
题意:给定一些高度都相同的海报去贴,问最后能看见几张海报
The picture below illustrates the case of the sample input.
View Code
题意:给定一些高度都相同的海报去贴,问最后能看见几张海报
The picture below illustrates the case of the sample input.
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; const int Max = 100000; //根据海报的个数来设置数组 struct node { int l,r; int cover; //海报的编号 int tag; //懒惰标志 }; node tree[Max * 8]; int t[4 * Max + 10],cnt,res[Max * 4 + 10]; int a[Max + 10],b[Max + 10]; void buildTree(int left, int right, int k) { tree[k].l = left; tree[k].r = right; tree[k].cover = 0; tree[k].tag = -1; if(left == right) return; int mid = (left + right) / 2; buildTree(left, mid, k * 2); buildTree(mid + 1, right, k * 2 + 1); } int Find(int l, int r, int key, int temp[]) { while(r >= l) { int mid = (l + r) / 2; if(temp[mid] == key) return mid; else if(temp[mid] > key) { r = mid - 1; } else { l = mid + 1; } } return -1; } void upDate(int left, int right, int k, int num) { if(tree[k].l == left && tree[k].r == right) { tree[k].cover = num; tree[k].tag = num; return; } if(tree[k].tag != -1) { tree[k * 2].tag = tree[k * 2 + 1].tag = tree[k].tag; tree[k * 2].cover = tree[k * 2 + 1].cover = tree[k].tag; tree[k].tag = -1; } int mid = (tree[k].l + tree[k].r) / 2; if(right <= mid) { upDate(left, right, k * 2, num); } else if(mid < left) { upDate(left, right, k * 2 + 1, num); } else { upDate(left, mid, k * 2, num); upDate(mid + 1, right, k * 2 + 1, num); } } void Search(int k) { if(tree[k].tag != -1) { tree[k].cover = tree[k].tag; tree[k * 2].tag = tree[k * 2 + 1].tag = tree[k].tag; tree[k * 2].cover = tree[k * 2 + 1].cover = tree[k].tag; tree[k].tag = -1; } if(tree[k].l == tree[k].r) { res[ tree[k].cover ] = 1; // 看看每一个点的海报编号 return; } Search(k * 2); Search(k * 2 + 1); } int main() { int test,n; scanf("%d", &test); while(test--) { scanf("%d", &n); cnt = 0; for(int i = 1; i <= n; i++) { scanf("%d%d", &a[i], &b[i]); t[ cnt++ ] = a[i]; t[ cnt++ ] = b[i]; //将所有的端点都放入t中 } sort(t, t + cnt); int cnt1 = 1; for(int i = 1; i < cnt; i++) { if(t[i] != t[i - 1]) //去掉相同的 t[ cnt1++ ] = t[i]; } for(int i = cnt1 - 1; i > 0; i--) { if(t[i] - t[i - 1] > 1) //如果相邻数差值大于1,就则加一个数 t[ cnt1++ ] = t[i - 1] + 1; } sort(t, t + cnt1); //加完之后排序,此时已经离散完毕 for(int i = cnt1; i > 0; i--) t[i] = t[i - 1]; //使区间为1到cnt1,好处理 buildTree(1, cnt1, 1); for(int i = 1; i <= n; i++) { int left = Find(1, cnt1, a[i], t); //二分查找出每个区间的端点在离散化后的数组中的位置 int right = Find(1, cnt1, b[i], t); upDate(left, right, 1, i); //更新,设置覆盖位为 i } memset(res, 0, sizeof(res)); Search(1); //从根开始查找 int ans = 0; for(int i = 1; i <= n; i++) if(res[i]) ans++; printf("%d\n", ans); } return 0; }
View Code
相关文章推荐
- overflow:hidden与margin:0 auto之间的冲突
- js循环使用
- Linux搭建
- CNN中感受野的计算
- 基本sql语句
- ubutnu 14.04LTS 安装opencv2.4
- string类型的查找
- jQuery--加一行减一行
- LeetCode 173. Binary Search Tree Iterator
- js限制input只能输入有效的数字,有且只有一个小数点,第一个不能为小数点-备
- javascript、js计算两个日期之间的天数
- Overlaying the Action Bar --1.1.4
- 深入探讨 Java 类加载器【转】
- guava学习笔记-集合
- React Native 的那些坑
- [ZOJ1654]Place the Robots 做题笔记
- 627 A codeforces
- 消费者监听JMS(二)
- jQuery--后台主机列表编辑
- 【LeetCode】289. Game of Life