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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
随机推荐
- service structure flowchart with full stack functionality in a brife map
More functionality will be added and running This diagram is just an easy chart for people to digest
- 正则表达式引擎:nfa的转换规则。
正则表达式引擎:nfa的转换规则. 正则到nfa 前言 在写代码的过程中,本来还想根据龙书上的说明来实现re到nfa的转换.可是写代码的时候发现,根据课本来会生成很多的无用过渡节点和空转换边,需要许多 ...
- Scrapy 通过登录的方式爬取豆瓣影评数据
Scrapy 通过登录的方式爬取豆瓣影评数据 爬虫 Scrapy 豆瓣 Fly 由于需要爬取影评数据在来做分析,就选择了豆瓣影评来抓取数据,工具使用的是Scrapy工具来实现.scrapy工具使用起来 ...
- .net程序员求职简历
.net程序员求职简历 个人概况 姓名 齐志超 学历 专科 毕业学校 河北软件职业技术学院 专业 软件开发与设计 手机 18730269286 年龄 22 性别 男 现居住地 北京 电子邮件 qzc9 ...
- ffmpeg利用libav库把yuv视频流转换为TS串流
今天到月末了,才发我这个月的第一篇文章,因为这个月前三周一直在看ffmpeg的libavcodec和libavformat两个库源码.实验室要做一个“小传大”的软件,就是android手机或平板电脑的 ...
- 分享下mac安装xamarin跨平台开发环境的坑
之前在vs2015上安装好了xamarin环境,考虑到调试IOS仍然需要mac机,昨天决定直接在mac上安装xamarin. 安装完所有的效果如上图,此时已经可以创建安卓和IOS环境. 我安装过程中, ...
- ColumnEdit 数据源修改
应用场景 当从ColumnEdit(如SearchLookUpEdit)中选取一条记录后,ColumnEdit的数据源不再出现这条记录.效果图如下 选择前 选择一条记录后,上一条记录不再显示. 此处是 ...
- 怎样在linux或者Unix上检查端口是否在使用
英文原文链接:https://www.cyberciti.biz/faq/unix-linux-check-if-port-is-in-use-command/ Question 1: 怎样在lin ...
- hdu1037
#include <iostream> #include <cstdio> using namespace std; int main() { int a,b,c; while ...
- Apache2.2下载及安装
php5.5 + apache2.4 安装配置图文步骤 http://wenku.baidu.com/link?url=8OHaJATVBHP5QrD-J2pTkmBOjY-ZG5cDngKMz7wl ...
题目链接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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
More functionality will be added and running This diagram is just an easy chart for people to digest
正则表达式引擎:nfa的转换规则. 正则到nfa 前言 在写代码的过程中,本来还想根据龙书上的说明来实现re到nfa的转换.可是写代码的时候发现,根据课本来会生成很多的无用过渡节点和空转换边,需要许多 ...
Scrapy 通过登录的方式爬取豆瓣影评数据 爬虫 Scrapy 豆瓣 Fly 由于需要爬取影评数据在来做分析,就选择了豆瓣影评来抓取数据,工具使用的是Scrapy工具来实现.scrapy工具使用起来 ...
.net程序员求职简历 个人概况 姓名 齐志超 学历 专科 毕业学校 河北软件职业技术学院 专业 软件开发与设计 手机 18730269286 年龄 22 性别 男 现居住地 北京 电子邮件 qzc9 ...
今天到月末了,才发我这个月的第一篇文章,因为这个月前三周一直在看ffmpeg的libavcodec和libavformat两个库源码.实验室要做一个“小传大”的软件,就是android手机或平板电脑的 ...
之前在vs2015上安装好了xamarin环境,考虑到调试IOS仍然需要mac机,昨天决定直接在mac上安装xamarin. 安装完所有的效果如上图,此时已经可以创建安卓和IOS环境. 我安装过程中, ...
应用场景 当从ColumnEdit(如SearchLookUpEdit)中选取一条记录后,ColumnEdit的数据源不再出现这条记录.效果图如下 选择前 选择一条记录后,上一条记录不再显示. 此处是 ...
英文原文链接:https://www.cyberciti.biz/faq/unix-linux-check-if-port-is-in-use-command/ Question 1: 怎样在lin ...
#include <iostream> #include <cstdio> using namespace std; int main() { int a,b,c; while ...
php5.5 + apache2.4 安装配置图文步骤 http://wenku.baidu.com/link?url=8OHaJATVBHP5QrD-J2pTkmBOjY-ZG5cDngKMz7wl ...