您的位置:首页 > Web前端

HDU 3465 Life is a Line 树状数组求逆序数

2016-10-13 16:20 381 查看

Life is a Line

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 192 Accepted Submission(s): 71
 
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

题目大意:

给出  一个区间  ( l  r),给出 n条直线,问这些直线有多少交点在区间内。

思路;

我们先求出给出每条直线在  l   r  上交点,如果   两条直线相交,那么    a  直线在 l  上的交点 在  b  直线在  l  上的交点下面  并且,a 直线在 r 上的交点在  b 直线与 r  交点的上方,或者是反过来,因此想到用逆序数来解决这个问题。

我们首先按照在  l  上交点 从小到大排序,然后编上序号,按照r上的顺序,从大到小排序,统计就可以了。

特殊考虑的地方:

直线和 y 轴平行。

实话,printf  比 cout 快

AC代码:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
struct qqq
{
double  ll;
double  rr;
int pos;
}qq[50005];
bool cmp1(const qqq &a,const qqq &b)
{
if(a.ll==b.ll)
return a.rr<b.rr;
return a.ll<b.ll;
}
bool cmp2(const qqq &a,const qqq &b)
{
if(a.rr==b.rr)
{
return a.ll>b.ll;
}
return a.rr>b.rr;
}
int a[50005];
int MAXN=50005;
int	lowbit(int	x)
{
return	x&(-x);
}
void add(int x,int add)
{
while(x<=MAXN)
{
a[x]+=add;
x+=lowbit(x);
}
}
int	get_sum(int	x)
{
int	ret=0;
while(x!=0)
{
ret+=a[x];
x-=lowbit(x);
}
return	ret;
}
int main()
{
int n;
double l,r;
double x1,y1,x2,y2;
double k,b;
while(~scanf("%d",&n))
{
int t=0;
int tt=0;
scanf("%lf%lf",&l,&r);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
if(x1==x2)
{
if(x1>l&&x1<r)
{
tt++;
}
continue;
}
k=(y2-y1)/(x2-x1);
b=y1-k*x1;
qq[t].ll=l*k+b;
qq[t++].rr=r*k+b;
}
sort(qq,qq+t,cmp1);
for(int i=0;i<t;i++)
{
qq[i].pos=i+1;
}
sort(qq,qq+t,cmp2);
memset(a,0,sizeof(a));
int ans=0;
for(int i=0;i<t;i++)
{
add(qq[i].pos,1);
ans+=get_sum(qq[i].pos-1);
}
printf("%d\n",ans+tt*t);
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 树状数组