3
// ranking each element to make segment tree of small size4
void compress(vector<int> &a) {6
sort(b.begin(), b.end());8
int prev = b[0], rnk = 0, n = a.size();9
for (int i = 0; i < n; i++) {16
for (int i = 0; i < n; i++) a[i] = mp[a[i]];19
void update(int st[], int tind, int ind, int val, int tl, int tr) {25
int m = tl + (tr - tl) / 2, left = tind << 1;27
update(st, left, ind, val, tl, m);29
update(st, left + 1, ind, val, m + 1, tr);30
st[tind] = max(st[left], st[left + 1]);33
int query(int st[], int tind, int tl, int tr, int ql, int qr) {34
if (tl > tr or ql > tr or qr < tl) return 0;35
if (ql <= tl and tr <= qr) return st[tind];36
int m = tl + (tr - tl) / 2, left = tind << 1;37
return max(query(st, left, tl, m, ql, qr), query(st, left + 1, m + 1, tr, ql, qr));40
vector<int> longestObstacleCourseAtEachPosition(vector<int> &a) {44
memset(st, 0, sizeof(st));45
update(st, 1, a[0], 1, 0, n - 1);49
for (i = 1; i < n; i++) {50
int mx = query(st, 1, 0, n - 1, 0, a[i]);52
update(st, 1, a[i], dp[i], 0, n - 1);