题目连接:http://poj.org/problem?id=1436

题意:给一些线段,每个线段有三个值y1, y2, x代表起点为(x, y1),终点为(x, y2)的线段。当从一个线段可以作水平线到另一个线段并且不穿过其他线段时,就称这两个线段时水平可见的。当三个线段可以两两水平可见,就称为形成一个线段三角。问:在这些线段中有多少个这样的线段三角?

分析:可以把每条线段看做是一个点,如果它和其他线段是水平可见的,就将这两个点相连,由于是无向图,就是你能看到我,我也能看到你,所以需要连接两次(map[a][b] = 1; map[b][a] = 1;)。然后问题就是如何生成存放线段关系的图,可以用线段树来求。假如现在遍历到第i条线段,那么第i条线段所能看到的是前面区间最新的线段,如图:

线段5只能看到1、2、4,不能看到3,所以可以用线段树区间修改的方法来生成这个树。

初始化set数组(存放线段的标号)全为-1,当遍历到某条线段时,对线段的那段区间进行查询,如果查询到的区间有值,说明可以看到线段set[o],然后即相连,如果查询到的区间一直是-1,就一直深搜,直到到达叶子节点返回。查询结束之后将当前线段插入到线段树中,即把区间更新。因为都是整数,所以某两条线段可见可能是在0.5的时候可见,所以需要预处理一下线段的区间,将区间扩大至2倍即可。

建完图之后暴力枚举每三个点即可。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 8000;
struct segment{int a, b, x;bool operator < (const segment& temp) const {return x < temp.x; }
}a[maxn+10];
int set[8*maxn+10];
bool map[maxn+10][maxn+10];
void push_down(int o){if (set[o] != -1){//将其左孩子和右孩子赋为和父亲一样的标号 set[o<<1] = set[o];set[o<<1|1] = set[o];set[o] = -1;//因为该区间已经不是一条线段全部覆盖了,所以标记重新初始化 }
}
void query(int o, int L, int R, int i){if (set[o] != -1){//区间有值,说明可以看到set[o],将其连接 map[i][set[o]] = 1;map[set[o]][i] = 1;return;}if (L == R){//没有值,还是初始状态,到叶子节点返回 return;}int m = (L+R)>>1;if (a[i].a <= m) query(o<<1, L, m, i);if (a[i].b > m) query(o<<1|1, m+1, R, i);
}
void insert(int o, int L, int R, int i){if (a[i].a <= L && a[i].b >= R){set[o] = i;//找到区间,将节点的值赋为i,表示这段区间可以看到第i条线段 return;}push_down(o);//节点信息向下更新 int m = (L+R)>>1;if (a[i].a <= m) insert(o<<1, L, m, i);if (a[i].b > m) insert(o<<1|1, m+1, R, i);
}
int main(){int T, n;scanf("%d", &T);while (T--){scanf("%d", &n);memset(set, -1, sizeof(set));//初始化为-1 memset(map, false, sizeof(map));//初始化为不相连 int L = (1<<31)-1, R = -1;for (int i=0; i<n; i++){scanf("%d%d%d", &a[i].a, &a[i].b, &a[i].x);a[i].a*=2;//预处理 a[i].b*=2;L = min(L, a[i].a);R = max(R, a[i].b);}sort(a, a+n);//将线段按照x从小到大排序 for (int i=0; i<n; i++){query(1, L, R, i);insert(1, L, R, i);}int ans = 0;//枚举三个线段,符合条件结果+1 for (int i=0; i<n; i++){for (int j=i+1; j<n; j++){if (map[i][j]){for (int k=j+1; k<n; k++){if (map[i][k] && map[j][k]){ans++;}}}}}printf("%d\n", ans);}return 0;
}

POJ 1436 Horizontally Visible Segments(线段树建图+枚举)相关推荐

  1. poj 1436 Horizontally Visible Segments

    题目大意: 在一个平面内,有一些竖直的线段,若两条竖直线段之间可以连一条水平线,这条水平线不与其他竖直线段相交,称这两条竖直线段为"相互可见"的.若存在三条竖直线段,两两" ...

  2. CodeForces - 786BLegacy——线段树建图+最短路

    [题目描述] CodeForces - 786BLegacy [题目分析] 题目大概意思就是有三种操作: 从某个点到另一个点 从某个点到另一个区间 从某个区间到另一个点 然后询问从其中一个点到其他所有 ...

  3. hdu 5420 Victor and Proposition(强连通+线段树建图)

    题意:给出一棵树,每个点都给一个x,d,代表它和x这个点以及以下深度差小于d的点都有一条有向边,求互相可达的u,v对数. 做法:可以很容易发觉如果我们把点连好然后直接找强连通分量,然后答案就是每个强连 ...

  4. hdu 5420 Victor and Proposition 线段树建图+强连通分量

    题意: http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=620&pid=1003 题目求有多少对互为充要 ...

  5. poj 1436 zoj 1391 Horizontally Visible Segments (Segment Tree)

    ZOJ :: Problems :: Show Problem 1436 -- Horizontally Visible Segments 用线段树记录表面能被看见的线段的编号,然后覆盖的时候同时把能 ...

  6. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线

    D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...

  7. POJ 1177 Picture [离散化+扫描线+线段树]

    http://poj.org/problem?id=1177 给若干矩形,求被覆盖的区域的周长. 将 y 坐标离散化后,按 x 坐标进行扫描.用线段树维护两个东西,当前竖线的叠加长度 len 和 条数 ...

  8. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

  9. poj 2777 AND hdu 5316 线段树

    区间染色问题,用线段树可以解决.颜色总类不多,故考虑用二进制数的每一位表示一种颜色,然后父节点的颜色就是孩子节点颜色"或"起来,加上lazy标记,轻松AC. poj 2777: 1 ...

  10. POJ 2777 Count Color (线段树区间修改 + 状态压缩)

    题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时  板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...

最新文章

  1. git换行符之autoCRLF配置的意义
  2. Leetcode刷题第1题:两数之和(基于Java语言)
  3. 原码一位乘法器设计_对原码、反码和补码的加深理解
  4. sso和oauth2.0的简单了解学习
  5. OpenStack部署笔记和安装WindowsXP镜像
  6. 学以致用十三-----Centos7.2+python3+YouCompleteMe成功历程
  7. Laravel5.5之事件监听、任务调度、队列
  8. 谐波分析显著性检验matlab,关于谐波检测方法的MATLAB仿真及综合性能分析.pdf
  9. deepin开机未登录自动连接wifi
  10. Unity3D基础38:角色控制器组件
  11. Micro Sip 配置自己的freeswitch服务器地址
  12. poj3764解题报告
  13. Eplan Electric P8 2.7安装流程
  14. 利用Gecco爬取(蚂蚁短租网)列表页数据
  15. android 实现谷歌地图
  16. Ubuntu18.04LTS安装TigerVNC
  17. Go语言黑帽子学习1
  18. tinymce粘贴word图片问题解决
  19. NLP标签/关键词-提取工具-java开发
  20. 5G时代来临,电影行业面临的机遇与挑战

热门文章

  1. Smartbi电子表格创建查询条件
  2. python除数为0报错_python——异常
  3. 基于C++的深度学习模型部署
  4. DBeaver Column repay _ script _ sql is read-only : Nocorresponding table column问题
  5. 谢震业,离“苏神”还有多远?
  6. Mac顶部菜单栏(Menubar)卡死
  7. 网管的自我修养-信息系统
  8. ViewportWidth,Width,MeasuredWidth
  9. js-鼠标事件-拖放图片(对鼠标事件进一步加深印象)
  10. Battery (Coin Change)