ZOJ

pro:给定平面上N条直线,保证没有直线和Y轴平行。 求有多少交点的X坐标落在(L,R)开区间之间,注意在x=L或者R处的不算。

sol:求出每条直线与L和R的交点,如果A直线和B直线在(L,R)相交,一定有Xa<Xb而且Ya>Yb(或相反);那么即是求逆序对。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pdd pair<double,double>
#define ll long long
using namespace std;
const int maxn=10010;
struct point{
    double x,y;
    point(){}
    point(double xx,double yy):x(xx),y(yy){}
}s[maxn];
struct line{
    point s,p;
    line(){}
    line(point xx,point yy):s(xx),p(yy){}
};
point operator *(double t,point a){ return point(t*a.x,t*a.y);}
point operator -(point w,point v){return point(w.x-v.x,w.y-v.y);}
point operator +(point w,point v){return point(w.x+v.x,w.y+v.y);}
double det(point w,point v){ return w.x*v.y-w.y*v.x;}
double dot(point w,point v){ return w.x*v.x+w.y*v.y;}
point inters(line a,line b){
    point p=a.s-b.s;
    double t=det(b.p,p)/det(a.p,b.p);
    return a.s+t*a.p;
}
int sum[maxn],b[maxn],N; double L,R,a[maxn];
point A[maxn],B[maxn]; ll ans;
line F,C;
struct in{
    double a,b; int id;
    bool friend operator<(in w,in v){
        if(w.a==v.a) return w.b<v.b;
        return w.a<v.a;
    }
}fcy[maxn],ys[maxn];
void add(int x){
    while(x<=N) {
        sum[x]++;
        x+=(-x)&x;
    }
}
int query(int x){
    int res=0; while(x){
        res+=sum[x];
        x-=(-x)&x;
    }
    return res;
}
int main()
{
    while(~scanf("%d",&N)&&N){
        rep(i,1,N)
          scanf("%lf%lf%lf%lf",&A[i].x,&A[i].y,&B[i].x,&B[i].y);
        scanf("%lf%lf",&L,&R);
        F=line(point(L,0.0),point(0.,1.0));
        C=line(point(R,0.0),point(0.,1.0));
        rep(i,1,N) {
            point tA=A[i],tB=B[i];
            A[i]=inters(line(tA,tB-tA),F);
            B[i]=inters(line(tA,tB-tA),C);
        }
        rep(i,1,N) fcy[i].a=A[i].y,fcy[i].b=B[i].y;

        sort(fcy+1,fcy+N+1);
        rep(i,1,N) ys[i].a=fcy[i].b,ys[i].id=i;
        sort(ys+1,ys+N+1);
        rep(i,1,N) a[i]=ys[i].a;
        rep(i,1,N) b[ys[i].id]=lower_bound(a+1,a+N+1,ys[i].a)-a;
        ans=0;
        rep(i,1,N) sum[i]=0;
        for(int i=N;i>=1;i--){
            ans+=query(b[i]-1);
            add(b[i]);
        }
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/10990069.html