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
  | // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	const int INF = 2000000000;
	int n;
	if (!(cin >> n)) return 0;
	vector<pair<int,int>> p(n + 1); // p[i] = {start, end}
	vector<pair<int,int>> s(n + 1), e(n + 1);
	for (int i = 1; i <= n; ++i) {
		int a, b; cin >> a >> b;
		p[i] = {a, b};
		s[i] = {a, i};
		e[i] = {b, i};
	}
	sort(s.begin() + 1, s.begin() + n + 1);
	sort(e.begin() + 1, e.begin() + n + 1);
	int K = 1;
	while ((1 << K) <= n) ++K;
	vector<vector<int>> dp(n + 1, vector<int>(K, 0));
	vector<pair<int,int>> stk; // (end, idx), strictly increasing by end
	stk.emplace_back(INT_MIN, 0); // sentinel
	int j = 1, prv = 0;
	for (int idx = 1; idx <= n; ++idx) {
		int cur = s[idx].second;
		while (j <= n && e[j].first < p[cur].first) {
			int t = e[j].second;
			if (p[prv].first < p[t].first) prv = t; // prev with maximum start among those ended
			++j;
		}
		while (!stk.empty() && stk.back().first >= p[cur].second) stk.pop_back();
		stk.emplace_back(p[cur].second, cur);
		dp[cur][0] = prv;
		for (int k = 1; k < K; ++k) dp[cur][k] = dp[dp[cur][k - 1]][k - 1];
	}
	auto f = [&](int l, int r) -> int {
		auto it = lower_bound(stk.begin(), stk.end(), make_pair(r, 0));
		if (it == stk.begin()) return 0;
		int x = prev(it)->second;
		if (p[x].first <= l) return 0;
		int ret = 1;
		for (int k = K - 1; k >= 0; --k) {
			int y = dp[x][k];
			if (p[y].first > l) {
				x = y;
				ret += (1 << k);
			}
		}
		return ret;
	};
	int M = f(0, INF);
	cout << M << "\n";
	map<int,int> mp; // boundary map: start -> end for selected intervals
	mp[0] = 0;
	mp[INF] = INF;
	bool first = true;
	for (int i = 1; i <= n; ++i) {
		auto it = mp.lower_bound(p[i].first);
		if (it == mp.end()) continue;
		auto rIt = it;
		if (it == mp.begin()) continue;
		auto lIt = prev(it);
		if (lIt->second < p[i].first && p[i].second < rIt->first) {
			int L = lIt->second, R = rIt->first;
			if (f(L, R) == f(L, p[i].first) + 1 + f(p[i].second, R)) {
				if (!first) cout << ' ';
				cout << i;
				first = false;
				mp[p[i].first] = p[i].second;
			}
		}
	}
	cout << "\n";
	return 0;
}
  |