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;
}
|