• 计蒜客 直线的交点(计算几何 + 逆序对)


    题目链接 直线的交点

    两条直线的交点如果落在两个平板之内的话

    假设这两条直线和两条平板的交点横坐标分别为  $x1, x2, X1, X2$

    那么有$(x2 - x1)(X2 - X1) < 0$

    于是这就转化成了一个经典问题

    我们求出所有直线和平板的两个交点的横坐标,按其中一个平板的横坐标排序,

    然后对另一个平板的横坐标求逆序对即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    
    double k, b1, b2;
    double a[N], b[N];
    int f[N], t[N], n;
    LL  ans = 0;
    
    struct node{
    	double x, y;
    	int id;
    	friend bool operator < (const node &a, const node &b){
    		return a.x < b.x;
    	}
    } c[N];
    
    
    bool cmp(const node &a, const node &b){ return a.y < b.y; }
    double calc(double k1, double b1, double k2, double b2){ return (b2 - b1) / (k1 - k2);}
    
    void update(int x){ for (; x <= n; x += x & -x) ++t[x];}
    int query(int x){ int ret(0); for (; x; x -= x & -x) ret += t[x]; return ret;}
    
    
    int main(){
    
    	scanf("%lf%lf%lf", &k, &b1, &b2);
    	scanf("%d", &n);
    
    	rep(i, 1, n) scanf("%lf%lf", a + i, b + i);
    	rep(i, 1, n) c[i].x = calc(a[i], b[i], k, b1);
    	rep(i, 1, n) c[i].y = calc(a[i], b[i], k, b2);
    
    	sort(c + 1, c + n + 1);
    	rep(i, 1, n) c[i].id = i;
    	sort(c + 1, c + n + 1, cmp);
    	rep(i, 1, n) f[c[i].id] = i;
    
    	dec(i, n, 1) ans += (LL)query(f[i] - 1), update(f[i]);
    
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    4.0中的并行计算和多线程详解(一)
    Dojo工具包简介
    javascript中event.keyCode
    iText简介(转)
    ServletContext
    java文件加解密算法
    ResultSet 的相关介绍
    spring的AOP的四种实现方式
    java实现文件zip压缩或者解压缩
    Hibernate查询数据的几种方式以及HQL用法及参数的几种使用方法
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7534983.html
Copyright © 2020-2023  润新知