Cod sursa(job #3259942)

Utilizator KRISTY06Mateiu Ianis Cristian Vasile KRISTY06 Data 28 noiembrie 2024 15:40:11
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 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);
    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 && a[newValue.second] < a[tree[currentNode].second]) {
        tree[currentNode] = newValue;
        return;
    } else if (left == right && a[newValue.second] >= a[tree[currentNode].second]) {
        return;
    }
    update(left, (left + right) / 2, currentNode * 2, pos, newValue);
    update((left + right) / 2 + 1, right, currentNode * 2 + 1, pos, newValue);
    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];
    }
    a[0] = 2e9 + 1;
    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, res.first + 1, {res.first + 1, i});
    }
    fout << ansLen << '\n';
    output(lastPos);
    return 0;
}