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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
随机推荐
- U盘读不出+卷标丢失+像读卡器+大小0+无媒体
U盘读不出+卷标丢失+像读卡器+大小0+无媒体 标题有点怪,原因是我不都不知道该怎样概括这个鸟问题,所以尽可能列出一些主要现象,希望有需要的童鞋搜到.但比标题更怪的是问题本身,且听我道来: 陪伴我若干 ...
- 算法线性编程珠玑读书笔记之----->使用线性算法求解连续子序列的最大和
这段时间笔者几篇文章介绍了改算法线性的文章. 关联文章的地址 这个算法我在我的博客里应用动态规划做过,详细实现请参阅我的dp板块,下面给出书上最快的算法,时间复杂度为O(n),称之为线性算法. #in ...
- <meta>标签的作用
<META> 是放于 <HEAD> 与 </HEAD>之间的标记,功用与变化等对,所以我公式化地介绍. <meta name="Descriptio ...
- About大数据插码
大数据插码主要用于在用户浏览网页和填写信息后抓取对应数据,这样就可以清晰的知道每个页面有多少用户浏览过,跳出率是多少以及用户的相应信息等. 大数据插码其实很简单,主要有以下注意事项: 1.引入相应的j ...
- Ionic的项目结构-工程目录
做前端的都应该知道一个框架 Ionic 这个是移动端webAPP最好用的吧(个人认为),那今天就来说说这个项目的结构以及文件的含义,希望对大家有所帮助 想看如何生成文件的话详细看我上篇博客 在用编 ...
- java基础练习 6
public class Sixth { /*一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程 找出1000以内的所有完数.*/ public sta ...
- PWA - 渐进式网络应用初认识
Progressive Web Apps 简称PWA,是一种接近原生用户体验的渐进增强的web-app.从浏览器演进而来,沉浸式的体验,改进web的性能低下等.是Google 在2015年提出,今年才 ...
- linux查找文件的命令【转】
原文链接:http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html 1. fi ...
- Ueditor文件上传问题
我们在做一些网站是会遇到,要有上传文件一类的事情. 我发现百度的富文本编辑器带上传功能,但是没有办法给后台传递我们要的参数. 先在ueditor.all.js中找到, me.execCommand(' ...
- 《数学分析Analysis》の 学习笔记
>> 皮亚诺(Peano)公理 定义自然数 公理2.1 0是一个自然数. 公理2.2 若n是自然数, 则n++也是自然数. 公理2.3 0不是任何自然数的后继, 即对于每个自然 ...
题目链接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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
U盘读不出+卷标丢失+像读卡器+大小0+无媒体 标题有点怪,原因是我不都不知道该怎样概括这个鸟问题,所以尽可能列出一些主要现象,希望有需要的童鞋搜到.但比标题更怪的是问题本身,且听我道来: 陪伴我若干 ...
这段时间笔者几篇文章介绍了改算法线性的文章. 关联文章的地址 这个算法我在我的博客里应用动态规划做过,详细实现请参阅我的dp板块,下面给出书上最快的算法,时间复杂度为O(n),称之为线性算法. #in ...
<META> 是放于 <HEAD> 与 </HEAD>之间的标记,功用与变化等对,所以我公式化地介绍. <meta name="Descriptio ...
大数据插码主要用于在用户浏览网页和填写信息后抓取对应数据,这样就可以清晰的知道每个页面有多少用户浏览过,跳出率是多少以及用户的相应信息等. 大数据插码其实很简单,主要有以下注意事项: 1.引入相应的j ...
做前端的都应该知道一个框架 Ionic 这个是移动端webAPP最好用的吧(个人认为),那今天就来说说这个项目的结构以及文件的含义,希望对大家有所帮助 想看如何生成文件的话详细看我上篇博客 在用编 ...
public class Sixth { /*一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程 找出1000以内的所有完数.*/ public sta ...
Progressive Web Apps 简称PWA,是一种接近原生用户体验的渐进增强的web-app.从浏览器演进而来,沉浸式的体验,改进web的性能低下等.是Google 在2015年提出,今年才 ...
原文链接:http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html 1. fi ...
我们在做一些网站是会遇到,要有上传文件一类的事情. 我发现百度的富文本编辑器带上传功能,但是没有办法给后台传递我们要的参数. 先在ueditor.all.js中找到, me.execCommand(' ...
>> 皮亚诺(Peano)公理 定义自然数 公理2.1 0是一个自然数. 公理2.2 若n是自然数, 则n++也是自然数. 公理2.3 0不是任何自然数的后继, 即对于每个自然 ...