HDU 3465 Life is a Line (逆序数 + 数状数组)
2017-07-05 16:18
471 查看
Life is a Line |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) |
Total Submission(s): 217 Accepted Submission(s): 81 |
Problem DescriptionThere is a saying: Life is like a line, some people are your parallel lines, while others are destined to meet you.Maybe have met, maybe just a matter of time, two unparallel lines will always meet in some places, and now a lot of life (i.e. line) are in the same coordinate system, in a given open interval, how many pairs can meet each other? |
InputThere are several test cases in the input.Each test case begin with one integer N (1 ≤ N ≤ 50000), indicating the number of different lines.Then two floating numbers L, R follow (-10000.00 ≤ L < R ≤ 10000.00), indicating the interval (L, R).Then N4000lines follow, each line contains four floating numbers x1, y1, x2, y2 (-10000.00 ≤ x1, y1, x2, y2 ≤ 10000.00), indicating two different points on the line. You can assume no two lines are the same one.The input terminates by end of file marker. |
OutputFor each test case, output one integer, indicating pairs of intersected lines in the open interval, i.e. their intersection point’s x-axis is in (l, r). |
Sample Input3 0.0 1.0 0.0 0.0 1.0 1.0 0.0 2.0 1.0 2.0 0.0 2.5 2.5 0.0 |
Sample Output1 问题:求在 (l, r)范围内有多少个交点,看起来好像是个几何题。。。时间上是一个求逆序数的问题。只要直线不平行于y轴就一定会 跟 x = l, x = r这两条直线相交。对于任意两条直线x=l,和x=r的交点分别为xl,xr,两直线在(L,R)相交,必然有 xl1>xl2&&xr1<xr2 或者 xl1<xl2&&xr1>xr2,(A.L-B.L)*(A.R-B.R)<0 所以可以用逆序数来求解。如果将与L的交点从小到大排,那么当相应的R的交点出现一个逆序数对就表示有两直线有交点. 先将所有直线根据l递增排序,之后编号1~n,再根据r递减排序,得到一个编号序列。 例如3412,递减,其中r3>r4>r1>r2, 又编号:l1<l2<r3<r4,1234=>所以12 34 所以3和4有交点,1和2有交点。 这符合逆序数的关系:一个数的逆序数是在它之前比他大的数的个数, 当然这里是小的数,原因是为了方便树状数组处理。所以只要根据上述方法排序再求逆序数即可。 1.与y轴平行得线,只要这样的线在(l,r)范围内,则必定跟别的不平行线相交。 所以计算下个数在乘积 2.l和r相同的情况。当l相同时,r递增排序;当r相同时,l递减排序。 就能使在l和r上的交点不计算在内。 (这一段转的别人的) #include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;const int maxn = 50000;struct Line{double a, b;int num;}line[50050];int tree[50500];int lowbit(int x) {return x & (-x);}void add(int pos) {for (int i = pos; i <= maxn; i += lowbit(i)) {tree[i]++;}}int sum(int pos) {int ans = 0;for (int i = pos; i >= 1; i -= lowbit(i)) {ans += tree[i];}return ans;}int main() {int n;double left, right;double x1, x2, y1, y2;while (cin >> n) {int parallel_y = 0;int unparallel = 0;scanf("%lf%lf", &left, &right);for (int i = 0; i < n; ++i) {scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);if (x1 == x2) {if (x1 > left && x1 < right) {parallel_y++;}} else {double k = (y1 - y2) / (x1 - x2);double b = y1 - k * x1;line[unparallel].a = left * k + b;line[unparallel++].b = right * k + b;}}sort(line, line + unparallel, [](Line l1, Line l2)->bool{return l1.a == l2.a ? l1.b < l2.b : l1.a < l2.a;});for (int i = 0; i < unparallel; ++i) {line[i].num = i + 1;}sort(line, line + unparallel, [](Line l1, Line l2)->bool{return l1.b == l2.b ? l1.a > l2.a : l1.b > l2.b;});memset(tree, 0, sizeof(tree));int ans = 0;for (int i = 0; i < unparallel; ++i) {add(line[i].num);ans += sum(line[i].num - 1);}cout << ans + unparallel * parallel_y << endl;}} |
相关文章推荐
- hdu 3465 Life is a Line(树状数组求逆序对)
- hdu 3465 Life is a Line 树状数组求逆序数
- hdu 3465 Life is a Line 树状数组求逆序数
- HDU 3465 Life is a Line 树状数组求逆序数
- HDOJ 题目3465 Life is a Line(树状数组求逆序对)
- HDU - 3465 Life is a Line
- hdu 3465 Life is a Line
- HDU - 3465 Life is a Line
- HDU 3465 Life is a Line 逆序数
- HDU3465--Life is a Line(树状数组求逆序数,离散化)
- HDOJ 题目3465 Life is a Line(树状数组求逆序对,第二种写法)
- HDU3465 Life is a Line 用归并排序求逆序数
- HDU - 5792 World is Exploding(数状数组+?)
- HDU 5792 World is Exploding (树状数组逆序对)
- HDU 1394 树状数组求逆序对
- HDU 3874 Necklace (数状数组)
- HDOJ 题目1394 Minimum Inversion Number(数状数组求逆序对)
- hdu 5193 分块 树状数组 逆序对
- Inversion (hdu 4911 树状数组 || 归并排序 求逆序对)
- hdu2492 数状数组或者线段树