HDU3465--Life is a Line(树状数组求逆序数,离散化)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 201 Accepted Submission(s): 77
Problem Description
There is a saying: Life is like a line, some people are your parallel lines, while others are destined to meet you.
Maybe have met, maybe just a matter of time, two unparallel lines will always meet in some places, and now a lot of life (i.e. line) are in the same coordinate system, in a given open interval, how many pairs can meet each other?
Input
There are several test cases in the input.
Each test case begin with one integer N (1 ≤ N ≤ 50000), indicating the number of different lines.
Then two floating numbers L, R follow (-10000.00 ≤ L < R ≤ 10000.00), indicating the interval (L, R).
Then N lines follow, each line contains four floating numbers x1, y1, x2, y2 (-10000.00 ≤ x1, y1, x2, y2 ≤ 10000.00), indicating two different points on the line. You can assume no two lines are the same one.
The input terminates by end of file marker.
Output
For each test case, output one integer, indicating pairs of intersected lines in the open interval, i.e. their intersection point’s x-axis is in (l, r).
Sample Input
3
0.0 1.0
0.0 0.0 1.0 1.0
0.0 2.0 1.0 2.0
0.0 2.5 2.5 0.0
Sample Output
1
Author
iSea @ WHU
Source
2010 ACM-ICPC Multi-University Training Contest(3)——Host by WHU
Recommend
zhouzeyong
题意:
给一个开区间(l,r),给n个直线,问这些直线在这段区间里面有多少个交点。‘’
思路:
如果暴力求解的话,时间复杂度为n^2,大概为10^11,肯定会超时。
由于题目将x的坐标限定在了一个区间(l,r)内,考虑如下情况:
设直线1分别与x=l,x=r相交与L1,R1;直线2分别相交于L2,R2。若两直线在此区间内相交,必有
L1<L2&&R1>R2 或者 L1>L2&&R1<R2
(想象若两直线在(l,r)相交,则经过交点后,纵坐标的大小顺序一定会改变)
此即为逆序数对的性质,于是题目转化为了求逆序数对的个数:
还需注意两点:
另外很重要的一点,数据为实型数,需要对数据进行离散化处理,如此才能应用树状数组
关于离散化:http://blog.csdn.net/gokou_ruri/article/details/7723378
代码:
#include<bits/stdc++.h>
using namespace std; #define lowbit(x) (x&(-x))
const int N=5e4+10;
struct node{
double a,b;
int num;
};
node e[N];
int c[N];
double l,r; int cmp1(node x,node y) //left 递增排序
{
if(x.a==y.a)
return x.b<y.b;
return x.a<y.a;
} int cmp2(node x,node y) //right 递减排序
{
if(x.b==y.b)
return x.a>y.a;
return x.b>y.b;
} void add(int x,int val)
{
while(x<N)
{
c[x]+=val;
x+=lowbit(x);
}
} int sum(int x)
{
int ans=0;
while(x>0)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
} int main()
{
int n;
int t,tt,i,j,ans;
double x1,y1,x2,y2,k,b; while(scanf("%d",&n)!=EOF)
{
t=tt=0;
ans=0;
scanf("%lf%lf",&l,&r);
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);//两个点的横纵坐标
if(x1==x2)//横坐标相等 表示竖直的线 平行与y轴
{
if(l<x1&&x1<r)
tt++;
continue;
}
k=(y2-y1)/(x2-x1);//y=kx+b
b=y1-k*x1;
e[t].a=l*k+b;
e[t++].b=r*k+b;
}
//******************//
//离散化,由于想树状数组中add的是left,所以只对left离散化即可
sort(e,e+t,cmp1);
for(i=0;i<t;i++)//编号
e[i].num=i+1;//树状数组无下标0
//*******************//
sort(e,e+t,cmp2);//递减排序 3412
memset(c,0,sizeof(c));
for(i=0;i<t;i++)//统计
{
add(e[i].num,1);
ans+=sum(e[i].num-1);
}
printf("%d\n",ans+tt*t);//加上平行y轴的直线所产生的交点
}
}
HDU3465--Life is a Line(树状数组求逆序数,离散化)的更多相关文章
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...
- poj 2299 树状数组求逆序数+离散化
http://poj.org/problem?id=2299 最初做离散化的时候没太确定可是写完发现对的---由于后缀数组学的时候,,这样的思维习惯了吧 1.初始化as[i]=i:对as数组依照num ...
- hdu 5147 Sequence II (树状数组 求逆序数)
题目链接 Sequence II Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数)
链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...
- SGU180 Inversions(树状数组求逆序数)
题目: 思路:先离散化数据然后树状数组搞一下求逆序数. 离散化的方法:https://blog.csdn.net/gokou_ruri/article/details/7723378 自己对用树状数组 ...
- HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number ...
- Codeforces645B【树状数组求逆序数】
题意: 给你1-n的序列,然后有k次机会的操作,每一次你可以选择两个数交换. 求一个最大的逆序数. 思路: 感觉就是最后一个和第一个交换,然后往中间逼近,到最终的序列,用树状数组求一下逆序数. #in ...
- hdu5792 World is Exploding(多校第五场)树状数组求逆序对 离散化
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5792 题目描述:给你n个值,每个值用A[i]表示,然后问你能否找到多少组(a,b,c,d)四个编号,四 ...
- HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
随机推荐
- <<C++ Primer>> 第四章 表达式
术语表 第 4 章 表达式 算术转换(arithmetic conversion): 从一种算术类型转换成另一种算术类型.在二元运算符的上下文中,为了保留精度,算术转换通常把较小的类型转换成较大的类型 ...
- js知识点——2之navigator
navigator(领航者) 1.appCodeName(返回浏览器的代码名) var x= navigator; document.write("CodeName:"+x.app ...
- Mac 基于Anaconda的TensorFlow安装笔记
最近在中国大学MOOC平台学习北大的曹健老师上的“人工智能实践——Tensorflow”课程,开始我的人工智能之旅.第一天,讲解如何搭建实验室环境,我是mac系统,所以只写mac系统上的实验室环境安装 ...
- HBASE学习笔记(四)
这两天把要前几天的知识点回顾一下,接下来我会用自己对知识点的理解来写一些东西 一.知识点回顾 1.hbase集群启动:$>start-hbase.sh ===>hbase-daemon.s ...
- Vue配置bs环境
安装插件 jQuery >: cnpm install jquery vue/cli 3 配置jQuery:在vue.config.js中配置(没有,手动项目根目录下新建) const webp ...
- leetcode34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值,返回 [ ...
- 一个线程oom,进程里其他线程还能运行吗?
线程之间互相不影响:守护线程生活周期相同 引言 这题是一个网友@大脸猫爱吃鱼给我的提问,出自今年校招美团三面的一个真题.大致如下 一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运行么? ...
- 5月Linux市场Steam 份额在增长
随着新的一个月的开始,Valve公布了上个月的软件/硬件调查数据.在2019年5月,Steam Linux的使用率按百分比略微上升. 上个月,运行Linux的Steam用户比例(根据有争议的Steam ...
- 在控制台编译运行java程序详细指导
控制台编译运行.java文件 首先在cmd中输入java –version确定java环境变量是否已经配好 其次在cmd中输入javac –version 确定javac环境变量是否已经配好 在用cd ...
- tensorflow 学习教程
tensorflow 学习手册 tensorflow 学习手册1:https://cloud.tencent.com/developer/section/1475687 tensorflow 学习手册 ...