Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemid = 3128
Question: give you n straight lines (n <= 10000) and calculate the number of intersections in the (L, R) interval.
Solution: Calculate the intersection between each line and x = L and x = R respectively, and then convert the two ends of N line segments to X = L and x = R. There are several intersections, in this way, the reverse order number is solved.
#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const double eps = 1e-8;const int maxn = 10010;int c[maxn],ans;void update(int x,int d){for(;x>0;x-=x&-x) c[x]+=d;}int sum(int x){for(ans=0;x<maxn;x+=x&-x) ans+=c[x];return ans;}struct point {double x,y;};struct L{point a,b;double h1,h2;int id;}in[maxn];int tmp[maxn];int cmp(L x,L y){if(fabs(x.h1-y.h1)<eps) return x.h2<y.h2;return x.h1<y.h1;}int cmp2(L x,L y){if(fabs(x.h2-y.h2)<eps) return x.h1<y.h1;return x.h2<y.h2;}int main(){int n;double l,r;while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)scanf("%lf%lf%lf%lf",&in[i].a.x,&in[i].a.y,&in[i].b.x,&in[i].b.y);scanf("%lf%lf",&l,&r);for(int i=1;i<=n;i++){double k=(in[i].b.y-in[i].a.y)/(in[i].b.x-in[i].a.x);in[i].h1=k*(l-in[i].a.x)+in[i].a.y;in[i].h2=k*(r-in[i].a.x)+in[i].a.y;}sort(in+1,in+n+1,cmp);for(int i=1;i<=n;i++)in[i].id=i;sort(in+1,in+n+1,cmp2);for(int i=1;i<=n;i++) tmp[in[i].id]=i;memset(c,0,sizeof(c));int s=0;for(int i=1;i<=n;i++){s+=sum(tmp[i]+1);update(tmp[i],1);}printf("%d\n",s);}return 0;}