Cod sursa(job #3261956)

Utilizator KRISTY06Mateiu Ianis Cristian Vasile KRISTY06 Data 7 decembrie 2024 22:09:43
Problema Subsir crescator maximal Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.2 kb
#include <bits/stdc++.h>
using namespace std;

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

pair<int, int> tree[400001];

vector<pair<int, int>> numPos;

//set<int> sortedNums;

//map<int, set<int>> numPos;

//vector<set<int>> numPos;

int neighbours[100001], a[100001];

pair<int, int> findMaxLen(int left, int right, int currentNode, int pos) {
    if (left > pos) {
        return {0, 0};
    } else if (right <= pos) {
        return tree[currentNode];
    }
    return max(findMaxLen(left, (left + right) / 2, currentNode * 2, pos), findMaxLen((left + right) / 2 + 1, right, currentNode * 2 + 1, pos));
}

void update(int left, int right, int currentNode, int newLen, int pos) {
    if (right < pos || left > pos) {
        return;
    } else if (left == right) {
        tree[currentNode] = {newLen, pos};
        return;
    }
    update(left, (left + right) / 2, currentNode * 2, newLen, pos);
    update((left + right) / 2 + 1, right, currentNode * 2 + 1, newLen, pos);
    tree[currentNode] = max(tree[currentNode * 2], tree[currentNode * 2 + 1]);
}

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

int main() {
    int n;
    fin >> n;
    for (int i = 1; i <= n; ++i) {
        fin >> a[i];
        numPos.push_back({a[i], i});
    }
    sort(numPos.begin(), numPos.end());
    int ansLen = 0, lastPos = 0, startSeqPos = 0, maxSubseqLastPos = numPos.front().second;
    pair<int, int> maxSubseq = {0, 0};
    for (int i = 0; i < numPos.size(); ++i) {
        if (numPos[startSeqPos].first == numPos[i].first) {
            pair<int, int> subseq = findMaxLen(1, n, 1, numPos[i].second - 1);
            if (subseq > maxSubseq) {
                maxSubseq = subseq;
                maxSubseqLastPos = numPos[i].second;
            }
          //  cout << "ok";
        }
        if (numPos[startSeqPos].first != numPos[i].first || i == numPos.size() - 1) {
        //    cout << maxSubseqLastPos << ' ';
            update(1, n, 1, maxSubseq.first + 1, maxSubseqLastPos);
            neighbours[maxSubseqLastPos] = maxSubseq.second;
            if (maxSubseq.first + 1 > ansLen) {
                ansLen = maxSubseq.first + 1;
                lastPos = maxSubseqLastPos;
            }
            startSeqPos = i;
            maxSubseqLastPos = numPos[i].second;
            maxSubseq = {0, 0};
            pair<int, int> subseq = findMaxLen(1, n, 1, numPos[i].second - 1);
            if (subseq > maxSubseq) {
                maxSubseq = subseq;
                maxSubseqLastPos = numPos[i].second;
            }
           if (i == numPos.size() - 1) {
            //    cout << maxSubseqLastPos << ' ';
                update(1, n, 1, maxSubseq.first + 1, maxSubseqLastPos);
                neighbours[maxSubseqLastPos] = maxSubseq.second;
                if (maxSubseq.first + 1 > ansLen) {
                    ansLen = maxSubseq.first + 1;
                    lastPos = maxSubseqLastPos;
                }
            }
           // cout << "ok";
        }
    }
    fout << ansLen << '\n';
    output(lastPos);
    return 0;
}