博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5862 Counting Intersections(离散化+树状数组)
阅读量:5443 次
发布时间:2019-06-15

本文共 2987 字,大约阅读时间需要 9 分钟。

HDU 5862 Counting Intersections(离散化+树状数组)

题目链接

Description

Given some segments which are paralleled to the coordinate axis. You need to count the number of their intersection.

The input data guarantee that no two segments share the same endpoint, no covered segments, and no segments with length 0.

Input

The first line contains an integer T, indicates the number of test case.

The first line of each test case contains a number n(1<=n<=100000), the number of segments. Next n lines, each with for integers, x1, y1, x2, y2, means the two endpoints of a segment. The absolute value of the coordinate is no larger than 1e9.

Output

For each test case, output one line, the number of intersection.

Sample Input

2

4
1 0 1 3
2 0 2 3
0 1 3 1
0 2 3 2
4
0 0 2 0
3 0 3 2
3 3 1 3
0 3 0 2

Sample Output

4

0

题意:

给你n(1<=n<=100000)条线段,每个线段平行于坐标轴的x轴或者y轴。问其中相交的点有多少。(线段之间最多只有一个交点。)

题解:

现在我们枚举平行于y轴的直线,然后扫一遍,找出有多少个平行于x轴的与之相交。

对于怎么求有多少个平行于x轴的与之相交。
首先因为我们对于直线的处理是按照x轴坐标排序,为什么这么排序,这样的话对于我们每一次扫描到平行于y轴的直线我们都不需要考虑其他左端点大于该平行于y轴的直线了。
至于查询,由于该平行于y轴的直线只会可能于左端点小于等于他的平行于x轴的直线有关,使用树状数组存储这个值。
至于这个值怎么存储?这里使用的是左端点值+1,右端点下一个点值-1。为什么这么做,首先如果这个点是大于右端点那么在树状数组累计的时候+1-1了。如果在左右端点之间那么数据直接+1了。这样可以方便的统计。

代码:

#include 
using namespace std;const int maxn = 101000;#define lowbit(x) (x&(-x))struct Node{ int type,x,y,y1; bool operator < (const Node & R)const{ return (x == R.x ? type < R.type : x < R.x); }}node[maxn*2];int Maxn;int cy[maxn*2];int bi[maxn*2];void add(int add,int n){ for (int i = add; i <= Maxn; i += lowbit(i)) bi[i] += n;}int sum(int n){ int ret = 0; for (int i = n; i > 0; i -= lowbit(i)) ret += bi[i]; return ret;}map
mp;int main(){ int t; scanf("%d",&t); while (t--){ mp.clear(); memset(bi,0,sizeof bi); int n; scanf("%d",&n); int cnode,ccy; cnode = ccy = 0; int x1,x2,y1,y2; for (int i = 1; i <= n; i++){ scanf("%d %d %d %d",&x1,&y1,&x2,&y2); if (x1 == x2){ if (y1 > y2) swap(y1,y2); node[++cnode]={1,x1,y1,y2}; cy[++ccy] = y1; cy[++ccy] = y2; }else { if (x1 > x2) swap(x1,x2); node[++cnode]={0,x1,y1,1}; node[++cnode]={0,x2+1,y2,-1}; cy[++ccy] = y1; } } sort(cy+1,cy+ccy+1); int acl = 0; for (int i = 1; i <= ccy; i++){ if (!mp[cy[i]]) mp[cy[i]] = ++ acl; } Maxn = acl; sort(node+1,node+cnode+1); long long ans = 0; for (int i = 1; i <= cnode; i++){ if (node[i].type){ ans += (sum(mp[node[i].y1]) - sum(mp[node[i].y]-1)); }else { add(mp[node[i].y],node[i].y1); } } printf("%lld\n",ans); } return 0; }
posted @
2016-08-19 17:01 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/thecoollight/p/5788283.html

你可能感兴趣的文章
ASP.NET性能优化之负载均衡
查看>>
黄聪:Mysql主从配置,实现读写分离
查看>>
mysql应用技巧
查看>>
项目整理 (一)
查看>>
0511Python基础-函数名应用-闭包-装饰器
查看>>
MSSQL 2005 列转行应用案例
查看>>
android--LinearLayout的child中layout_weight的作用与使用
查看>>
[转]Android中Spannable的使用
查看>>
安装SqlServer2005出现错误的解决办法
查看>>
SQL Server 备份数据库到指定路径,任务实现
查看>>
How to install redis server on CentOS 7 / RHEL 7
查看>>
MyEclipse编码设置
查看>>
GreenPlum之日常SQL脚本笔记(一)
查看>>
多语言对应的Alternate Character
查看>>
Oracle数据库中SYS、SYSTEM、DBSNMP、SYSMAN四用户的区别
查看>>
python学习笔记(七):面向对象编程、类
查看>>
写一下我的SublimeText3 for Python 的配置之路吧
查看>>
iOS 随笔小技巧 弱self 打印当前类行数列数,多人开发自动适配pch地址,获取设备uid的信息...
查看>>
面向对象复习
查看>>
isset()和empty()的区别
查看>>