Try Again

1107 斜率小于0的连线数量

二维平面上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\n",ans);
    return 0;
}

 

posted @ 2018-09-02 10:54  十年换你一句好久不见  阅读(392)  评论(0编辑  收藏  举报