Pagini recente » Cod sursa (job #3161558) | Cod sursa (job #891532) | Cod sursa (job #2547988) | Cod sursa (job #1897559) | Cod sursa (job #2773449)
#include <fstream>
using namespace std;
void scmax(const int *a, const int n, ofstream &out) {
// idx..[l] -> retine indexul elementului care termina ultimul scmax de
// lungime l gasit
int idxOfLastElementWihtinSubseqOfLength[n + 1];
int prev[n];
idxOfLastElementWihtinSubseqOfLength[0] = -1;
idxOfLastElementWihtinSubseqOfLength[1] = 0;
prev[0] = -1;
int maxLength = 1;
int i;
for (i = 1; i < n; i++) {
int left = 1;
int right = maxLength;
int mid;
// din subsirul crescator maxim de la pasul curent caut un element x
// care ar permite lui a[i] sa se concateneze la subsirul care se
// termina cu acel x;
// daca acest x e chiar ultimul element din scmaxul de la pasul curent
// inseamna ca obtin o noua solutie mai mare
while (left <= right) {
mid = ((right - left) >> 1) + left;
if (a[idxOfLastElementWihtinSubseqOfLength[mid]] < a[i]) {
// caut printre elemente mai mari de scmax[mid] din scmax
left = mid + 1;
} else {
// caut printre elemente mai mici de scmax[mid] din scmax
right = mid - 1;
}
}
// daca dupa ce am terminat cautarea am iesit cu capatul dinspre stanga
// la dreapta lui scmax[maxLength] inseamna ca a[i] e mai mare decat
// toate elementele din scmaxul curent, in special decat ultimul, si
// atunci pot extinde acest scmax cu a[i]
if (left == maxLength + 1)
++maxLength;
idxOfLastElementWihtinSubseqOfLength[left] = i;
prev[i] = idxOfLastElementWihtinSubseqOfLength[left - 1];
}
int scmaxElements[maxLength];
int j = maxLength - 1;
i = idxOfLastElementWihtinSubseqOfLength[maxLength];
while (i != -1) {
scmaxElements[j--] = a[i];
i = prev[i];
}
out << maxLength << '\n';
for (int j = 0; j < maxLength; j++)
out << scmaxElements[j] << ' ';
}
int main(void) {
ifstream in("scmax.in");
ofstream out("scmax.out");
int n;
in >> n;
int a[n];
for (int i = 0; i < n; i++)
in >> a[i];
scmax((const int *) a, n, out);
in.close();
out.close();
return 0;
}