Cod sursa(job #938176)

Utilizator blasterzMircea Dima blasterz Data 11 aprilie 2013 23:14:19
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <tr1/unordered_map>
using namespace std;
#define N 100001
#define common int m = (l + r) >> 1, L = n << 1, R = L | 1
int n;
int v[N];
int norm[N];
int x[N];
int dp[N];
int t[N];
int H[3 * N];
tr1::unordered_map<int, int> hash;

void update(int n, int l, int r, int p, int idx) {
    if (l >= r) {
        H[n] = idx;
        return;
    }
    common;
    if (p <= m)
        update(L, l, m, p, idx);
    else
        update(R, m + 1, r, p, idx);

    if (dp[ H[L] ] > dp[ H[R] ])
        H[n] = H[L];
    else
        H[n] = H[R];
}

int poz;
void query(int n, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
        if (dp[ H[n] ] > dp[ poz ])
            poz = H[n];
        return;
    }
    common;
    if (ql <= m)
        query(L, l, m, ql, qr);
    if (qr > m)
        query(R, m + 1, r, ql, qr);
}

int main() {
    freopen ("scmax.in", "r", stdin);
    freopen ("scmax.out", "w", stdout);

    scanf ("%d\n", &n);
    int i;
    for (i = 1; i <= n; ++i) {
        scanf ("%d", &v[i]);
        x[i] = v[i];
    }
    
    // normalizare
    sort (x + 1, x + n + 1);
    int nr = 0;
    hash[ x[1] ] = ++nr;
    for (i = 2; i <= n; ++i)
        if (x[i] != x[i - 1])
            hash[ x[i] ] = ++nr;

    for (i = 1; i <= n; ++i)
        norm[i] = hash[ v[i] ];
    
   // dinamica 
    dp[1] = 1;
    update(1, 1, nr, norm[1], 1);
    
    for (i = 2; i <= n; ++i) {
        poz = 0;
        if (norm[i] - 1 > 0)
            query(1, 1, nr, 1, norm[i] - 1);
        dp[i] = 1 + dp[poz];
        t[i] = poz;
        update(1, 1, nr, norm[i], i);
    }
    
    // reconstituire
    int mx = 0;
    poz = 0;
    for (i = 1; i <= n; ++i)
        if (dp[i] > mx)
            mx = dp[i],
            poz = i;
    printf ("%d\n", mx);
    vector<int> sol;
    for (i = poz; i; i = t[i])
        sol.push_back( v[i] );
    for (i = sol.size() - 1; i >= 0; --i)
        printf ("%d ", sol[i]);
    printf ("\n");
}