假几何真逆序数 NB HDU3465
生活随笔
收集整理的這篇文章主要介紹了
假几何真逆序数 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 }?
轉載于:https://www.cnblogs.com/oscar-cnblogs/p/7615527.html
總結
以上是生活随笔為你收集整理的假几何真逆序数 NB HDU3465的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java用毫秒数做日期计算的一个踩坑记录
- 下一篇: linux 安装lnmp