题意:求在[L,R]范围内直线交点的对数
思路:首先如果两条直线相交的话,那么(xl1-xl2)*(yl1-yl2)<0,这刚好满足求逆序数对的条件
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int MAXN = 50010;
struct node{
double x,y;
int id;
}a[MAXN];
int n,m,cnt;
double L,R;
int c[MAXN];
int lowbit(int x){
return x&(-x);
}
bool cmp1(node a,node b){
return a.x < b.x;
}
bool cmp2(node a,node b){
return a.y < b.y;
}
void update(int x,int d){
while (x < MAXN){
c[x] += d;
x += lowbit(x);
}
}
int sum(int x){
int ans = 0;
while (x > 0){
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main(){
while (scanf("%d",&n) != EOF){
m = cnt = 0;
scanf("%lf%lf",&L,&R);
for (int i = 1; i <= n; i++){
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
if (x1 == x2){
if (x1 > L && x1 < R)
m++;
}
else {
cnt++;
a[cnt].x = y1+(L-x1)*(y2-y1)/(x2-x1);
a[cnt].y = y1+(R-x1)*(y2-y1)/(x2-x1);
}
}
n = cnt;
sort(a+1,a+1+n,cmp1);
a[0].x = a[1].x - 1;
for (int j = 0,i = 1; i <= n; i++)
if (a[i].x == a[i-1].x)
a[i].id = j;
else a[i].id = ++j;
sort(a+1,a+1+n,cmp2);
memset(c,0,sizeof(c));
ll ans = 0;
for (int i = 1; i <= n; i++){
ans += i-1-sum(a[i].id);
update(a[i].id,1);
}
ans += (ll)m*n;
cout << ans << endl;
}
return 0;
}