• 假几何真逆序数 NB HDU3465


    题意:

    有n条直线,问他们两两在横坐标开区间(L,R)之间相交的个数

    n=50000,暴力肯定就不用想了,如果在纸上画一画可以发现如果两条直线在(L,R)内相交,那么他们与x= L和x=R的交点序数是相反的

    所以我们只需要算与x=L的交点,然后根据这些点排序编个号,在与R相交,根据新的交点排个逆序,根据编号求逆序数即可。

    需要注意的一点:两种特殊情况如果不与L,R相交,那么如果再这个区间内,必定所有直线都会与之相交,记录下数量。

    另一种情况就是,如果两个直线的交点正巧在x=L和x=R时, 这种情况是不能记录在内的,那么在之前排序的时候与L相交的交点按升序排列

    如果交点坐标相同按R交点坐标升序,再根据R的坐标排降序的时候,如果R坐标相同,根据L的坐标排降序,就可以避免这种情况计算在内了。

    求逆序数的时候是不会计算在里面的。

    求逆序数树状数组即可。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <queue>
      5 #include <vector>
      6 #include <algorithm>
      7 #include <stack>
      8 #include <set>
      9 #include <map>
     10 #include <cmath>
     11 #define pb push_back
     12 #define CLR(a) memset(a, 0, sizeof(a));
     13 #define MEM(a, b) memset(a, b, sizeof(a));
     14 #define fi first
     15 #define se second
     16 
     17 using namespace std;
     18 
     19 typedef long long ll;
     20 
     21 const int MAXN = 50007;
     22 const int MAXV = 207;
     23 const int MAXE = 207;
     24 const int INF = 0x3f3f3f3f;
     25  
     26 int n;
     27 
     28 struct Node
     29 {
     30     double a, b;
     31     int nu;
     32     Node () {}
     33     Node (double a, double b) : a(a), b(b) {}
     34 }node[MAXN];
     35 double L, R;
     36 
     37 bool cmpl(Node n1, Node n2)
     38 {
     39     if (n1.a == n2.a)
     40         return n1.b < n2.b;
     41     else return n1.a < n2.a;
     42 }
     43 bool cmpr(Node n1, Node n2)
     44 {
     45     if (n1.b == n2.b)
     46         return n1.a > n2.a;
     47     else return n1.b > n2.b;
     48 }
     49 int cnt = 0;
     50 int c[MAXN << 1];
     51 int lowbit(int x)
     52 {
     53     return x&(-x);
     54 }
     55 void modify(int x, int data)
     56 {
     57     for (int i = x; i < MAXN; i+= lowbit(i))
     58         c[i] += data;
     59 }
     60 int getsum(int x)
     61 {
     62     int res = 0;
     63     for (int i = x; i > 0; i -= lowbit(i))
     64         res += c[i];
     65     return res;
     66 }
     67 
     68 int main()
     69 {
     70     while (~scanf("%d", &n))
     71     {
     72         CLR(node);
     73         CLR(c);
     74         scanf("%lf%lf", &L, &R);
     75         cnt = 0;
     76         int vrtcl = 0;
     77         for (int i = 0; i < n; i++)
     78         {
     79             double x1, y1, x2, y2;
     80             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
     81             if (x1 == x2)
     82             {
     83                 if (x1 > L && x1 < R) vrtcl++;
     84                 continue;
     85             }
     86             double k = (y2-y1)/(x2-x1);
     87             double b = y2 - k*x2;
     88             double l = k*L+b, r = k*R+b;
     89             node[cnt++] = Node(l, r);
     90         }
     91         sort(node, node+cnt, cmpl);
     92         for (int i = 0; i < cnt; i++) node[i].nu = i+1;
     93         sort(node, node+cnt, cmpr);
     94         //for (int i = 0; i < cnt; i++) cout << node[i].nu << endl;
     95         int ans = 0;
     96         for (int i = 0; i < cnt; i++)
     97         {
     98             ans += getsum(node[i].nu);
     99             modify(node[i].nu, 1);
    100         }
    101         ans += cnt*vrtcl;
    102         cout << ans << endl;
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    Django(app的概念、ORM介绍及编码错误问题)
    Django(完整的登录示例、render字符串替换和redirect跳转)
    Construct Binary Tree from Preorder and Inorder Traversal
    Single Number II
    Single Number
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Binary Tree Zigzag Level Order Traversal
    Recover Binary Search Tree
    Add Binary
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/7615527.html
Copyright © 2020-2023  润新知