51 Nod 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) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现