Link to this code: https://cses.fi/paste/f182380c809de295d80fc0/
/* 777 */
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9 + 7;

struct Range {
    int start;
    int end;
    int index;
};

void solve() {
    int N;
    cin >> N;
    vector<Range> events(N);
    for (int i = 0; i < N; ++i) {
        cin >> events[i].start;
        cin >> events[i].end;
        events[i].index = i;
    }

    // early starts, late ends first (longer durations first as tie-breakers)
    sort(events.begin(), events.end(), [](Range event1, Range event2) {
        return (event1.start == event2.start) ? event1.end > event2.end
                                              : event1.start < event2.start;
    });

    // is range at `index` contained inside any other range
    vector<int> contained(N), contains(N);
    int cur_max = 0;
    for (int i = 0; i < N; ++i) {
        Range range = events[i];
        if (cur_max >= range.end) contained[range.index] = 1;
        cur_max = max(cur_max, range.end);
    }

    // does range at `index` contains any other range inside it
    int cur_min = INF;
    for (int i = N - 1; i >= 0; --i) {
        Range range = events[i];
        if (cur_min <= range.end) contains[range.index] = 1;
        cur_min = min(cur_min, range.end);
    }

    for (int x : contains) cout << x << " ";
    cout << '\n';
    for (int x : contained) cout << x << " ";
}

int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--) solve();
}

/*
- can be solved using brute -> O(n^2)
- for optimisation -> we need the intervals in a specific order
- sorting! but based on what (starts or ends ?)
- for simplicity lets choose start (left->right is traditional)
- now we do not have to care about start anymore - only think about ends

left->right(1->N)
1. is the current interval contained inside any other interval
    - there need to exist an end before the current interval such that
      the end is greater than the current interval end
    - this implies that the current interval is contained inside that end
    - how? track the maximum end of all the intervals before the current interval

right->left(N->1)
2. does the current interval contain any other interval inside it
    - there need to exist an end after the current interval such that
      the end is less than the current interval end
    - this implies that the current interval contains that end inside it
    - how? track the minimum end of all the intervals after the current interval

edgecases
- for intervals having same starting points we need to decide upon a criteria
  to sort the ends either greater first or smalller first
- with the below example we can decide that greater ends come first

[3,8], [3,10] -> !X! NO as we know that [3,8] is contained inside [3,10] - (1) & (2) fail
[3,10], [3,8] -> !✔️! YES as [3,8] is contained insdide [3,10] - (1) & (2) pass

conclusions
- all the intervals before the current interval start at or before the current start
- in case if two intervals start at the same time
    then all the intervals before the current interval end at or after the current interval ends
*/