Cod sursa(job #2742188)

Utilizator DragosC1Dragos DragosC1 Data 20 aprilie 2021 13:54:05
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;

int n, a[100001], poz[100001], shorten[100001], l, t[100001], dp[100001], fq[100001];
int longest, lung, clongest;
int rez[100001];

void read() {
    int i;
    ifstream f("scmax.in");
    f >> n; 
    for (i = 1; i <= n; i++)
        f >> a[i];
    f.close();
}

int query(int x) {
    int Max = 0;
    while (x) {
        if (dp[fq[x]] > dp[Max])
            Max = fq[x];
        x -= (x & -x);
    }
    return Max;
}

void update(int x, int ind) {
    while (x <= n) {
        if (dp[ind] > dp[fq[x]])
            fq[x] = ind;
        x += (x & -x);
    }
}

void solve() {
    int i;
    for (i = 1; i <= n; i++)
        poz[i] = shorten[i] = a[i];

    sort(shorten + 1, shorten + n + 1);
    l = 1;
    for (i = 2; i <= n; i++)
        if (shorten[i] != shorten[i - 1])
            shorten[++l] = shorten[i];

    for (i = 1; i <= n; i++)
        poz[i] = lower_bound(shorten + 1, shorten + l + 1, poz[i]) - shorten;
    
    for (i = 1; i <= n; i++) {
        t[i] = query(poz[i] - 1);
        dp[i] = dp[t[i]] + 1;
        update(poz[i], i);
    }

    for (i = 1; i <= n; i++)
        if (dp[i] > dp[longest])
            longest = i;
    clongest = longest;

    while (longest > 0) {
        rez[++lung] = a[longest];
        longest = t[longest];
    }

}

void output() {
    int i;
    ofstream g("scmax.out");
    g << dp[clongest] << '\n';
    for (i = lung; i >= 1; i--)
        g << rez[i] << ' ';
    g.close();
}

int main() {
    ios::sync_with_stdio(0);
    read();
    solve();
    output();
    return 0;
}