二维平面上N个点之间共有C(n,2)条连线。求这C(n,2)条线中斜率小于0的线的数量。
二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y)。例如:(2,3) (3,4) (1,5) (4,6),其中(1,5)同(2,3)(3,4)的连线斜率 < 0,因此斜率小于0的连线数量为2。
Input
第1行:1个数N,N为点的数量(0 <= N <= 50000) 第2 - N + 1行:N个点的坐标,坐标为整数。(0 <= X[i], Y[i] <= 10^9)
Output
输出斜率小于0的连线的数量。(2,3) (2,4)以及(2,3) (3,3)这2种情况不统计在内。
Input示例
4 2 3 3 4 1 5 4 6
Output示例
2
离散加树状数组
将点按照x轴排序后,一次将点的y值离散后加入到树状数组中
#include <bits/stdc++.h> using namespace std; #define lowbit(x) (x&(-x)) struct node{ int x,y; bool operator<(const node &a)const{ return a.x>x; } }e[50006]; int sum[50016]; void add(int x){ for(int i=x;i;i-=lowbit(i)) sum[i]++; } int query(int x) { int ans=0; for(int i=x;i<50005;i+=lowbit(i)) ans+=sum[i]; return ans; } int n,a[50006],b[50006]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&e[i].x,&e[i].y); a[i]=e[i].y; } sort(a+1,a+n+1); sort(e+1,e+n+1); int l=1,r=0; int ans=0; e[0].x=-1; for(int i=1;i<=n;i++) { if(e[i].x==e[i-1].x) r++; else if(e[i].x!=e[i-1].x){ for(int j=l;j<=r;j++) add(b[j]); l=i; r=i; } b[i]=lower_bound(a+1,a+n+1,e[i].y)-a; //printf("%d ",b[i]); ans+=query(b[i]+1); } printf("%d ",ans); return 0; }