LightOj1089(求点包含几个线段 + 线段树)
2016-03-08 23:43
309 查看
题目链接
题意:n( n <= 50000 ) 个线段,q ( q <= 50000) 个点,问每个点在几个线段上
线段端点的和询问的点的值都很大,所以必须离散化
第一种解法:先把所有的线段端点和询问点,离散处理,然后对于每条选段处理,c[x]++, c[y + 1]--,然后令c[x] = c[x] + c[x - 1],所以c[x]就保存了被几个线段覆盖,然后对对于每个询问点,查找他在离散后的位置,然后直接读取c[],这种方法很巧妙,佩服佩服
未AC
题意:n( n <= 50000 ) 个线段,q ( q <= 50000) 个点,问每个点在几个线段上
线段端点的和询问的点的值都很大,所以必须离散化
第一种解法:先把所有的线段端点和询问点,离散处理,然后对于每条选段处理,c[x]++, c[y + 1]--,然后令c[x] = c[x] + c[x - 1],所以c[x]就保存了被几个线段覆盖,然后对对于每个询问点,查找他在离散后的位置,然后直接读取c[],这种方法很巧妙,佩服佩服
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int Max = 50000 + 10; struct node { int l,r; int tag,cnt; }; node tree[4 * Max]; int a[4 * Max], b[4 * Max], c[4 * Max], querry[Max]; int tot; void buildTree(int left, int right, int k) { tree[k].l = left; tree[k].r = right; tree[k].tag = -1; tree[k].cnt = 0; if(left == right) return; int mid = (left + right) / 2; buildTree(left, mid, k * 2); buildTree(mid + 1, right, k * 2 + 1); } void upDate(int left, int right, int k, int newp) { if(tree[k].tag != -1) { tree[k * 2].tag = tree[k * 2 + 1].tag = tree[k].tag; tree[k * 2].cnt++; tree[k * 2 + 1].cnt++; tree[k].tag = -1; } if(tree[k].l == left && tree[k].r == right) { tree[k].cnt++; tree[k].tag = newp; return; } int mid = (tree[k].l + tree[k].r) / 2; if(right <= mid) upDate(left, right, k * 2, newp); else if(mid < left) upDate(left, right, k * 2 + 1, newp); else { upDate(left, mid, k * 2, newp); upDate(mid + 1, right, k * 2 + 1, newp); } } int Search(int k, int value) { if(tree[k].l == tree[k].r) return tree[k].cnt; if(tree[k].tag != -1) { tree[k * 2].tag = tree[k * 2 + 1].tag = tree[k].tag; tree[k * 2].cnt++; tree[k * 2 + 1].cnt++; tree[k].tag = -1; } int mid = (tree[k].l + tree[k].r) / 2; if(value <= mid) return Search(k * 2, value); else return Search(k * 2 + 1, value); } int main() { int test, n, q; scanf("%d", &test); for(int t = 1; t <= test; t++) { scanf("%d%d", &n, &q); tot = 0; for(int i = 1; i <= n; i++) { scanf("%d%d", &a[i], &b[i]); c[tot++] = a[i]; c[tot++] = b[i]; } for(int i = 1; i <= q; i++) { scanf("%d", &querry[i]); c[tot++] = querry[i]; } sort(c, c + tot); tot = unique(c, c + tot) - c; buildTree(1, tot, 1); for(int i = 1; i <= n; i++) { int x = lower_bound(c, c + tot, a[i]) - c + 1; int y = lower_bound(c, c + tot, b[i]) - c + 1; upDate(x, y, 1, 1); } printf("Case %d:\n", t); for(int i = 1; i <= q; i++) { int x = lower_bound(c, c + tot, querry[i]) - c + 1; printf("%d\n", Search(1, x)); } } return 0; }
未AC
相关文章推荐
- [everydayNote] 今天脑子不好使
- docker学习笔记6:利用dockerfile创建镜像介绍(生成简单web服务器镜像)
- Dropbox用户数量突破5亿
- Dropbox用户数量突破5亿
- 属性对话框自学笔记
- grep命令和正则表达式用法
- Intent应用详解
- cocos2dx 基础
- ubuntu配置vim为windows下C++编程风格
- Unity3D 5 官方教程:粒子系统 How-Tos
- [实战]HM-Router configuration for TP ROOM
- array和list的排序算法对比(一):快速排序
- Java 模拟Ajax上传文件
- 策略模式
- oracle中一些关于blob字段的操作
- Cucumber测试驱动开发
- DSA 算法
- 如何阅读他人的程序代码[转]
- hihoCoder Floyd算法
- Hadoop HA 搭建