-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathf_fastest.cpp
109 lines (95 loc) · 2.88 KB
/
f_fastest.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
This is the fastest solution that uses binary tree to store points left
to the current. This allows us to add new point and query number
of points less than current Y in O(log N) time. Thus whole time
complexity is O(N * log N), and the longest test case takes only 126ms
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T> struct Node {
T x;
int left_count = 0, right_count = 0, n = 1;
Node *left = NULL;
Node *right = NULL;
Node(T x) : x(x) {}
};
template <class T> class BinaryTree {
private:
Node<T> *root = NULL;
public:
void add(T x) {
if (this->root == NULL)
this->root = new Node<T>(x);
else {
auto cur = this->root;
while(1) {
if (x == cur->x) {
cur->n ++;
break;
} else if (x < cur->x) {
cur->left_count ++;
if (cur->left == NULL) {
cur->left = new Node<T>(x);
break;
} else
cur = cur->left;
} else {
cur->right_count ++;
if (cur->right == NULL) {
cur->right = new Node<T>(x);
break;
} else
cur = cur->right;
}
}
}
}
pair<int, int> count_less_and_eq(T x) {
int less = 0, eq = 0;
auto cur = this->root;
while (cur) {
if (x == cur-> x) {
less += cur->left_count;
eq = cur->n;
break;
} else if (x < cur->x) {
cur = cur->left;
} else {
less += cur->left_count + cur->n;
cur = cur->right;
}
}
return make_pair(less, eq);
}
};
int main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<pair<double, double>> a(n);
for (int i = 0; i < n; i ++) {
cin >> a[i].first;
cin >> a[i].second;
}
sort(a.begin(), a.end(), [](pair<double, double> &x, pair<double, double> &y) {
return x.first < y.first;
});
BinaryTree<double> tree;
double nom = 0, denom = 0;
for (int i = 0; i < n;) {
int j = i;
while (j < n && a[i].first == a[j].first) {
auto r = tree.count_less_and_eq(a[j].second);
nom += r.first + r.second / 2.0;
denom += i;
j ++;
}
for (int k = i; k < j; k ++)
tree.add(a[k].second);
i = j;
}
cout << nom / denom;
}