Number of Segments that Contain Each Other
I really did not know how to go about solving this problem.
Ran into this while doing a practice problem: https://codeforces.com/contest/1915/problem/F
You can brute force it in , but I had no idea on how to do it faster.
- I had some ideas of storing the start and end points, and somehow iterating through that
We can iterate over the segments in increasing order of the 𝑏 position and for each of them adding the number of segments that we have already passed that have an value larger than the one of the current segment.
- Yea, like I actually had many of the ideas, but couldn’t find a solution
Go through b in ascending order, and keep track of how many ‘a’s are in the set, which are greater than the current a!!
- That was actually very much my initial idea
So something like this, but the problem is that std::distance
can do O(n) worst case
- You want to do something like
it - s.begin()
, however that doesn’t work with a set
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int a[n];
int b[n];
vector<pair<int, int>> v;
for (int i = 0; i < n; i++) {
cin >> a[i];
cin >> b[i];
v.push_back({b[i], a[i]});
}
sort(v.begin(), v.end());
set<int> s;
int total = 0;
for (int i = 0; i < n; i++) {
auto it = s.upper_bound(v[i].second);
total += i - distance(s.begin(), it); // This works for edge case because s.begin() == s.end() when it's empty
s.insert(v[i].second);
}
cout << total << endl;
}
return 0;
}