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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
随机推荐
- tastypie Django REST API developement 1)
Read by linux/GNU commands Let's follow and start from here:http://django-tastypie.readthedocs.org/e ...
- Software Industry Revolution----POJ3898----DP
题目地址:http://poj.org/problem?id=3898 题目意思: 给你一个模式串,再给你一个原串,要你去匹配 模式串里面的?可对应任意一个字符 *号可对应0个或多个字符 其中a=1, ...
- 可供VC调用的QT编写的界面DLL方法
一般直接编写的QT动态库是无法被Windows下的VC6.0等调用的. 如下步骤 第一步:必须要在QT界面库源码下包含qtwinmigrate的源码包和库,网上可下载到. 第二步:在QT的proc文件 ...
- 结构-行为-样式-Bootstrap笔记
1.自上而下的内容布局,中间内容可变,应该用: <div class=" container-fluid"> <div class=" row" ...
- Hadoop学习之Ubuntu12.04 Hadoop 环境搭建笔记
SSH无密码配置 Hadoop在Ubuntu12.04上搭建环境 报错及问题 SSH无密码配置 参考:Linux(Centos)配置OpenSSH无密码登陆 注意问题: Hadoop集成环境三台机器都 ...
- ASP.NET Zero--8.一个例子(1)菜单添加
以一个商品分类管理功能来编写,代码尽量简单易懂.从一个实体开始,一直到权限控制,由浅到深一步步对功能进行完善. 1.打开语言文件 [..\MyCompanyName.AbpZeroTemplate.C ...
- 导入导出csv文件
在工作中需要把csv文件数据导入数据库或者把数据库数据导出为csv文件.以下是我的简单的实现. <?php class csv { public $db_connection; public $ ...
- linux面试题集锦2《转》
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 索引节点来 ...
- Elasticsearch 5.0 磁盘空间节省策略的认识
前言:本文是当时QQ群员讨论磁盘空间如何优化,我搜了下类似的文章,结合官方文档做了一些总结 参考文章1 参考文章2 如果你有疑问,可以联系我参与讨论,或者去原文查看. NOTE: 磁盘空间节省问题,是 ...
- CoreJavaE10V1P3.10 第3章 Java的基本编程结构-3.10 数组(Arrays)
数组是存储同一类型数据的数据结构 数组的声明与初始化 int[] a; int a[]; int[] a = new int[100]; int[] a = new int[100]; for (in ...
题目链接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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
Read by linux/GNU commands Let's follow and start from here:http://django-tastypie.readthedocs.org/e ...
题目地址:http://poj.org/problem?id=3898 题目意思: 给你一个模式串,再给你一个原串,要你去匹配 模式串里面的?可对应任意一个字符 *号可对应0个或多个字符 其中a=1, ...
一般直接编写的QT动态库是无法被Windows下的VC6.0等调用的. 如下步骤 第一步:必须要在QT界面库源码下包含qtwinmigrate的源码包和库,网上可下载到. 第二步:在QT的proc文件 ...
1.自上而下的内容布局,中间内容可变,应该用: <div class=" container-fluid"> <div class=" row" ...
SSH无密码配置 Hadoop在Ubuntu12.04上搭建环境 报错及问题 SSH无密码配置 参考:Linux(Centos)配置OpenSSH无密码登陆 注意问题: Hadoop集成环境三台机器都 ...
以一个商品分类管理功能来编写,代码尽量简单易懂.从一个实体开始,一直到权限控制,由浅到深一步步对功能进行完善. 1.打开语言文件 [..\MyCompanyName.AbpZeroTemplate.C ...
在工作中需要把csv文件数据导入数据库或者把数据库数据导出为csv文件.以下是我的简单的实现. <?php class csv { public $db_connection; public $ ...
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 索引节点来 ...
前言:本文是当时QQ群员讨论磁盘空间如何优化,我搜了下类似的文章,结合官方文档做了一些总结 参考文章1 参考文章2 如果你有疑问,可以联系我参与讨论,或者去原文查看. NOTE: 磁盘空间节省问题,是 ...
数组是存储同一类型数据的数据结构 数组的声明与初始化 int[] a; int a[]; int[] a = new int[100]; int[] a = new int[100]; for (in ...