51 Nod 1107 斜率小于0的连线数量

                         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从小到大排序
   仅当 e[i].y < e[i-1].y 时为一个合法的连线
   用树状数组 统计逆序对数
   由于y值较大 离散化一下比较好
 1 #include <cctype>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #define lowbit(x) x&(-x)
 5 
 6 const int MAXN=50010;
 7 
 8 int n,ans,tim;
 9 
10 int bit[MAXN<<1];
11 
12 struct node {
13     int x,y;
14     int num;
15 };
16 node e[MAXN];
17 
18 inline void read(int&x) {
19     int f=1;register char c=getchar();
20     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
21     for(;isdigit(c);x=x*10+c-48,c=getchar());
22     x=x*f;
23 }
24 
25 inline bool cmp(node x,node y) {return x.y<y.y;}
26 
27 inline bool _cmp(node x,node y) {
28     if(x.x==y.x) return x.y<y.y;
29     return x.x<y.x;
30 }
31 
32 inline void add(int x,int v) {
33     while(x<=tim) bit[x]+=v,x+=lowbit(x);
34 }
35 
36 inline int Query(int x) {
37     int sum=0;
38     while(x) sum+=bit[x],x-=lowbit(x);
39     return sum;
40 }
41 
42 int hh() {
43     read(n);
44     for(int i=1; i<=n; ++i) read(e[i].x),read(e[i].y);
45     
46     std::sort(e+1,e+1+n,cmp);
47     
48     e[1].num=++tim;
49     for(int i=2; i<=n; ++i) {
50         if(e[i].y==e[i-1].y) e[i].num=tim;
51         else e[i].num=++tim;
52     } 
53     
54     std::sort(e+1,e+1+n,_cmp);
55     add(e[1].num,1);
56     int sum=1;
57     for(int i=2; i<=n; ++i) {
58         ans+=sum-Query(e[i].num);
59         ++sum;
60         add(e[i].num,1);
61         if(e[i].x==e[i-1].x && e[i].y < e[i-1].y) --ans;
62     }
63     
64     printf("%d\n",ans);
65     
66     return 0;
67 }
68 
69 int sb=hh();
70 int main(int argc,char**argv) {;}
代码
posted @ 2017-10-25 16:01  拿叉插猹哈  阅读(156)  评论(0编辑  收藏  举报