Cod sursa(job #1472952)

Utilizator theep0Cruceru Radu theep0 Data 18 august 2015 11:11:24
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

struct NR {
    int p, v;
    NR (int p, int v): p(p), v(v) {}
    NR(){};
    bool operator<(const NR &c) const {
        return v < c.v;
    }
};


int n;
vector<NR> sc;
vector<int> sol;
int tmp[100001], dp[100001], arb[300003], pre[100001], init[100001];

int query(int i, int l, int r, int ql, int qr) {
    int m, lm = 0, rm = 0;
    if (ql <= l && qr >= r) {
        return arb[i];
    } else {
        m = (l + r)/2;
        if (ql <= m) lm = query(i*2, l, m, ql, qr);
        if (qr > m) rm = query(i*2+1, m + 1, r, ql, qr);
        if (dp[lm] >= dp[rm]) return lm;
        else return rm;
    }
}

void update(int i, int l, int r, int nod, int v) {
    int m;
    if (l != r) {
        m = (l + r)/2;
        if (nod <= m) {
            update(i*2, l, m, nod, v);
        } else {
            update(i*2 + 1, m+1, r, nod, v);
        }
        if (dp[arb[i*2]] >= dp[arb[i*2+1]]) {
            arb[i] = arb[i*2];
        } else {
            arb[i] = arb[i*2 + 1];
        }
    } else {
        arb[i] = v;
    }
}


int main() {
    int nr, i, j, prev;
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);
    cin >> n;
    for (i = 1; i <= n; i++) {
        cin >> nr;
        sc.push_back(NR(i, nr));
        init[i] = nr;
    }
    sort(sc.begin(), sc.end());
    nr = prev = 0;
    for (vector<NR>::iterator it = sc.begin(); it != sc.end(); it++) {
        if ((*it).v != prev) {
            nr++;
            prev = (*it).v;
        }
        tmp[(*it).p] = nr;
    }
    update(1, 1, n, tmp[1], 1);
    dp[1] = 1;
    pre[1] = 0;
    for (i = 2; i <=n; i++) {
        if (tmp[i] == 1) {
            dp[i] = 1;
            pre[i] = 0;
        } else {
            j = query(1, 1, n, 1, tmp[i] - 1);
            dp[i] = 1 + dp[j];
            pre[i] = j;
        }
        update(1, 1, n, tmp[i], i);
    }
    j = 0;
    prev = 0;
    for (i = 1; i <= n; i++) {
        if (dp[i] > prev) {
            prev = dp[i];
            j = i;
        }
    }
    cout << prev << "\n";
    while (j != 0) {
        sol.push_back(init[j]);
        j = pre[j];
    }
    for (vector<int>::reverse_iterator it = sol.rbegin(); it != sol.rend(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}