Pagini recente » Cod sursa (job #1484890) | Cod sursa (job #2197408) | Monitorul de evaluare | Monitorul de evaluare | Cod sursa (job #3307333)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
int max(int x, int y) {
return x > y ? x : y;
}
int next_power_2(int n) {
return (1 << (32 - __builtin_clz(n - 1)));
}
struct SegmentTree {
vector<int> tree;
int TREE_SIZE;
SegmentTree(int n) {
TREE_SIZE = next_power_2(n);
tree = vector<int> (TREE_SIZE << 1, 0);
}
void update(int pos, int val) {
pos += TREE_SIZE;
tree[pos] = max(tree[pos], val);
while (pos > 1) {
pos >>= 1;
tree[pos] = max(tree[pos << 1], tree[pos << 1 | 1]);
}
}
int query(int left, int right) {
int res = 0;
left += TREE_SIZE;
right += TREE_SIZE;
while (left <= right) {
if (left & 1)
res = max(res, tree[left++]);
if (!(right & 1))
res = max(res, tree[right--]);
left >>= 1;
right >>= 1;
}
return res;
}
};
int main() {
int n;
fin >> n;
vector<int> x(n), f(n);
vector<int> aux(n);
for (int i = 0; i < n; i++) {
fin >> x[i];
aux[i] = x[i];
}
sort(aux.begin(), aux.end());
aux.erase(unique(aux.begin(), aux.end()), aux.end());
auto idx = [&](int val) {
return lower_bound(aux.begin(), aux.end(), val) - aux.begin();
};
for (int i = 0; i < n; i++)
x[i] = idx(x[i]);
SegmentTree st(n);
int res = 0, len;
for (int i = 0; i < n; i++) {
len = st.query(0, x[i] - 1) + 1;
f[i] = len;
st.update(x[i], len);
res = max(res, len);
}
fout << res << "\n";
stack<int> lis;
int i = n - 1, j = res;
while (j > 0) {
while (i >= 0 && f[i] != j)
i--;
lis.push(aux[x[i]]);
j--;
}
while (!lis.empty()) {
fout << lis.top() << " ";
lis.pop();
}
fin.close();
fout.close();
return 0;
}