Pagini recente » Cod sursa (job #3207878) | infoarena - comunitate informatica, concursuri de programare | Cod sursa (job #861803) | Cod sursa (job #3249180) | Cod sursa (job #2975587)
#include <cstdio>
#include <memory>
#include <algorithm>
#include <vector>
using namespace std;
class Solver{
private:
int N;
vector<int> v;
vector<int> DP; // DP[i] = smallest end value of a stricly increasing subsequence of length i
vector<int> indexDP; // indexDP[i] = the index in v for DP[i]
vector<int> parent; // parent[i] = the index in v for v[i]'s predecesor
public:
Solver() {
freopen("scmax.in", "r", stdin);
freopen("scmax.out", "w", stdout);
}
~Solver() {
fclose(stdin);
fclose(stdout);
}
void readData() {
scanf("%d", &N);
v.resize(N);
for (int i = 0; i < N; ++i)
scanf("%d", &v[i]);
}
void solveLongestIncreasing() {
parent.resize(N);
DP.emplace_back(v[0]);
indexDP.emplace_back(0);
parent[0] = -1;
for (int i = 1; i < N; ++i) {
vector<int>::iterator lowestIt = lower_bound(DP.begin(), DP.end(), v[i]);
if (lowestIt == DP.end()) {
parent[i] = indexDP.back();
DP.emplace_back(v[i]);
indexDP.emplace_back(i);
continue;
}
int lowestIndex = distance(DP.begin(), lowestIt);
if (lowestIndex)
parent[i] = indexDP[lowestIndex - 1];
else
parent[i] = -1;
DP[lowestIndex] = v[i];
indexDP[lowestIndex] = i;
}
vector<int> ans(DP.size());
int bestIndex = indexDP[(int) DP.size() - 1];
for (int i = (int) DP.size() - 1; i >= 0; --i) {
ans[i] = v[bestIndex];
bestIndex = parent[bestIndex];
}
printf("%d\n", (int)ans.size());
for (auto it: ans)
printf("%d ", it);
printf("\n");
}
};
int main() {
unique_ptr<Solver> s = make_unique<Solver>();
s->readData();
s->solveLongestIncreasing();
return 0;
}