Cod sursa(job #3259919)

Utilizator KRISTY06Mateiu Ianis Cristian Vasile KRISTY06 Data 28 noiembrie 2024 15:16:52
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

int pos[100001];
int a[100001];

pair<int, int> tree[400001]; // {subseqLen, lastPos}

void output(int currentPos) {
    if (pos[currentPos] == 0) {
        fout << a[currentPos] << ' ';
        return;
    }
    output(pos[currentPos]);
    fout << a[currentPos] << ' ';
}

pair<int, int> findMaxSubseqLen(int left, int right, int currentNode, int endPos, int pos) {
    if (left > endPos || (left == right && a[tree[currentNode].second] >= a[pos])) {
        return {0, 0};
    } else if (right <= endPos && a[tree[currentNode].second] < a[pos]) {
        return tree[currentNode];
    }
    pair<int, int> res1 = findMaxSubseqLen(left, (left + right) / 2, currentNode * 2, endPos, pos);
    pair<int, int> res2 = findMaxSubseqLen((left + right) / 2 + 1, right, currentNode * 2 + 1, endPos, pos);
   /* if (res1.first == res2.first && a[res1.second] < a[res2.second]) {
        return res1;
    } else if (res1.first == res2.first && a[res1.second] >= a[res2.second]) {
        return res2;
    } */
    return max(res1, res2);
}

void update(int left, int right, int currentNode, int pos, pair<int, int> newValue) {
    if (right < pos || left > pos) {
        return;
    } else if (left == right) {
        tree[currentNode] = newValue;
        return;
    }
    update(left, (left + right) / 2, currentNode * 2, pos, newValue);
    update((left + right) / 2 + 1, right, currentNode * 2 + 1, pos, newValue);
    if (tree[currentNode * 2].first == tree[currentNode * 2 + 1].second && a[tree[currentNode * 2].second] < a[tree[currentNode * 2 + 1].second]) {
        tree[currentNode] = tree[currentNode * 2];
    } else if (tree[currentNode * 2].first == tree[currentNode * 2 + 1].second && a[tree[currentNode * 2].second] >= a[tree[currentNode * 2 + 1].second]) {
        tree[currentNode] = tree[currentNode * 2 + 1];
    } else {
        tree[currentNode] = max(tree[currentNode * 2], tree[currentNode * 2 + 1]);
    }
}

int main() {
    int n;
    fin >> n;
    for (int i = 1; i <= n; ++i) {
        fin >> a[i];
    }
    int ansLen = 1, lastPos = 1;
    update(1, n, 1, 1, {1, 1});
    for (int i = 2; i <= n; ++i) {
        pair<int, int> res = findMaxSubseqLen(1, n, 1, i - 1, i);
        pos[i] = res.second;
        if (res.first + 1 > ansLen) {
            ansLen = res.first + 1;
            lastPos = i;
        }
        update(1, n, 1, i, {res.first + 1, i});
    }
    fout << ansLen << '\n';
    output(lastPos);
    return 0;
}