HDU 5862 Counting Intersections(离散化+树状数组)
HDU 5862 Counting Intersections(离散化+树状数组)
题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862
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 <bits/stdc++.h>
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 <int,int>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;
}
HDU 5862 Counting Intersections(离散化+树状数组)的更多相关文章
- HDU 5862 Counting Intersections (树状数组)
Counting Intersections 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Description Given ...
- HDU 5862 Counting Intersections 扫描线+树状数组
题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Counting Intersections Time Limit: 12000/ ...
- hdu 3015 Disharmony Trees (离散化+树状数组)
Disharmony Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 5862 Counting Intersections (离散化+扫描线+树状数组)
题意:给你若干个平行于坐标轴的,长度大于0的线段,且任意两个线段没有公共点,不会重合覆盖.问有多少个交点. 析:题意很明确,可是并不好做,可以先把平行与x轴和y轴的分开,然后把平行y轴的按y坐标从小到 ...
- Hdu 5862 Counting Intersections(有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点+树状数组区间求和单点跟新)
传送门:Hdu 5862 Counting Intersections 题意:有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点 分析: 基本的操作流程是:先将所有的线段按照横树坐标x按小的 ...
- HDU 6318.Swaps and Inversions-求逆序对-线段树 or 归并排序 or 离散化+树状数组 (2018 Multi-University Training Contest 2 1010)
6318.Swaps and Inversions 这个题就是找逆序对,然后逆序对数*min(x,y)就可以了. 官方题解:注意到逆序对=交换相邻需要交换的次数,那么输出 逆序对个数 即可. 求逆序对 ...
- 【bzoj4756】[Usaco2017 Jan]Promotion Counting 离散化+树状数组
原文地址:http://www.cnblogs.com/GXZlegend/p/6832263.html 题目描述 The cows have once again tried to form a s ...
- hdu 5862 Counting Intersections
传送门:hdu 5862 Counting Intersections 题意:对于平行于坐标轴的n条线段,求两两相交的线段对有多少个,包括十,T型 官方题解:由于数据限制,只有竖向与横向的线段才会产生 ...
- CodeForces 540E - Infinite Inversions(离散化+树状数组)
花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
随机推荐
- struts2对ognl表达式的使用(配图解加讲解)
ognl它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航. 先看一张示意图 如果是下面的除了第一种valueStack的下面几 ...
- centos 6.4 x64安装bugfree
第一步:下载xampp-linux-1.8.1.tar.gz [root@SVNMANAGER ~]# tar -zxvf xampp-linux-1.8.1.tar.gz -C /opt [root ...
- [置顶] 安卓UI组件之ListView详解
ListView是很常见的一个UI组件,在许多App中都很常用,其意思就是可滚动的列表,使用ListView必须使用Adapter(适配器),常用的适配器友谊ArrayAdapter,SimpleAd ...
- IP、子网的详述 ——IP分类、网关地址,子网掩码、子网作用(转)
IP地址 在Internet上连接的所有计算机,从大型机到微型计算机都是以独立的身份出现,我们称它为主机.为了实现各主机间的通信,每台主机都必须有一个唯一的网络地址.就好像每一个住宅都有唯一的门 ...
- 读书笔记:《HTML5开发手册》Web表单
这是补充HTML5基础知识的第五篇内容,其他为: 一.HTML5-- 新的结构元素 二.HTML5-- figure.time.details.mark 三.HTML5-- details活学活用 四 ...
- [ios] Xcode使用设置相关-快捷键【转】
快照: command+control+s 编辑完了可以和之前的某个版本对比,通过File->Snapshots 调试时的快捷键也像大多数 IDE 靠拢了,采用了 F5.F6.F7 简单 ...
- html5新标签布局应用指南
html5中为了便于设计者的网站布局新添加了一些标签,本文主要讲解这些标签的实际应用方法. 大多数前端的朋友在设计网站时主要应用<div>标签构造盒子进行布局,这是种非常高效的方法,可以将 ...
- Spring总结 0.概述
由于之前学了好多知识,感觉挺乱的.趁放假,想对这些知识复习归纳下.所以就有了这些随笔啦.随笔中可能会出现错误哈,万一有人看了并且发现了留言哈.勿喷,谢谢哈~先对Spring进行简要概括,以下内容有些摘 ...
- HTTP协议----ETag
Etag是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等.具体内部含义是服务器控制的,就像Cookie那样. 服务器首先产生ETag,服务器可在稍后使用它来 ...
- 设计模式 -- 桥接模式(Bridge Pattern)
桥接模式 Bridge Pattern 结构设计模式 定义: 分离抽象部分和实现部分,使他们独立运行. 避免使用继承导致系统类个数暴增,可以考虑桥接模式. 桥接模式将继承关系转化为关联关系,减少耦合, ...
题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862
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 <bits/stdc++.h>
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 <int,int>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;
}
Counting Intersections 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Description Given ...
题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Counting Intersections Time Limit: 12000/ ...
Disharmony Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
题意:给你若干个平行于坐标轴的,长度大于0的线段,且任意两个线段没有公共点,不会重合覆盖.问有多少个交点. 析:题意很明确,可是并不好做,可以先把平行与x轴和y轴的分开,然后把平行y轴的按y坐标从小到 ...
传送门:Hdu 5862 Counting Intersections 题意:有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点 分析: 基本的操作流程是:先将所有的线段按照横树坐标x按小的 ...
6318.Swaps and Inversions 这个题就是找逆序对,然后逆序对数*min(x,y)就可以了. 官方题解:注意到逆序对=交换相邻需要交换的次数,那么输出 逆序对个数 即可. 求逆序对 ...
原文地址:http://www.cnblogs.com/GXZlegend/p/6832263.html 题目描述 The cows have once again tried to form a s ...
传送门:hdu 5862 Counting Intersections 题意:对于平行于坐标轴的n条线段,求两两相交的线段对有多少个,包括十,T型 官方题解:由于数据限制,只有竖向与横向的线段才会产生 ...
花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
ognl它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航. 先看一张示意图 如果是下面的除了第一种valueStack的下面几 ...
第一步:下载xampp-linux-1.8.1.tar.gz [root@SVNMANAGER ~]# tar -zxvf xampp-linux-1.8.1.tar.gz -C /opt [root ...
ListView是很常见的一个UI组件,在许多App中都很常用,其意思就是可滚动的列表,使用ListView必须使用Adapter(适配器),常用的适配器友谊ArrayAdapter,SimpleAd ...
IP地址 在Internet上连接的所有计算机,从大型机到微型计算机都是以独立的身份出现,我们称它为主机.为了实现各主机间的通信,每台主机都必须有一个唯一的网络地址.就好像每一个住宅都有唯一的门 ...
这是补充HTML5基础知识的第五篇内容,其他为: 一.HTML5-- 新的结构元素 二.HTML5-- figure.time.details.mark 三.HTML5-- details活学活用 四 ...
快照: command+control+s 编辑完了可以和之前的某个版本对比,通过File->Snapshots 调试时的快捷键也像大多数 IDE 靠拢了,采用了 F5.F6.F7 简单 ...
html5中为了便于设计者的网站布局新添加了一些标签,本文主要讲解这些标签的实际应用方法. 大多数前端的朋友在设计网站时主要应用<div>标签构造盒子进行布局,这是种非常高效的方法,可以将 ...
由于之前学了好多知识,感觉挺乱的.趁放假,想对这些知识复习归纳下.所以就有了这些随笔啦.随笔中可能会出现错误哈,万一有人看了并且发现了留言哈.勿喷,谢谢哈~先对Spring进行简要概括,以下内容有些摘 ...
Etag是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等.具体内部含义是服务器控制的,就像Cookie那样. 服务器首先产生ETag,服务器可在稍后使用它来 ...
桥接模式 Bridge Pattern 结构设计模式 定义: 分离抽象部分和实现部分,使他们独立运行. 避免使用继承导致系统类个数暴增,可以考虑桥接模式. 桥接模式将继承关系转化为关联关系,减少耦合, ...