Cod sursa(job #1294401)

Utilizator danalexandruDan Alexandru danalexandru Data 17 decembrie 2014 15:15:56
Problema Subsir crescator maximal Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>


using namespace std;

const int maxn = 100005;

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


/*
lung = 1,   1,  2,  3,  1,  2,  4,  5,  5,  3
pref = 0,   0,  2,  3,  0,  5,  4,  7,  7,  6
    lung[1]=1;
    for(i=1;i<=n;i++){
        lmax=0;
        for(j=1;j<i;j++)
            if(v[j]<v[i]){
                lmax=lung[j];
                pred[i]=j;
            }
        lung[i]=1+lmax;
    }

lung subsirului cresc maximal --> max(lung[i])
                                    1<=i<=n

void subsir (int p){
        if(pred[p]!=0)
            subsir(pred[p])
        out<<v[p]<<" ";
        }

*/
int n;
int a[maxn];
int m[maxn];
int f[maxn];

int b[maxn], lung;

void citire() {
    in >> n;
    for (int i = 1; i <= n; ++i)
        in >> a[i];
}

void sol() {
    b[ lung = 0 ] = 0;

    int pow = 1;
    for (int i = 1; i <= n; ++i) {
        while ((pow << 1) <= lung) pow <<= 1;

        int an = 0;
        for (int stp = pow; stp; stp >>= 1)
            if (an + stp <= lung && a[b[an + stp]] < a[i])
                an += stp;

        m[i] = m[b[an]] + 1;
            f[i] = b[an];

        if (an == lung)
            b[++lung] = i;
        else
            if (a[b[an+1]] > a[i])
                b[an+1] = i;
    }
}
void g(int poz) {
    if (poz == 0) return;
    g(f[poz]);
    out << a[poz] << " ";
}

void scrie() {
    out << lung << endl;
    for (int i = 1; i <= n; ++i)
        if (m[i] == lung) {
            g(i);
            return;
        }
}

int main() {
    scrie();
    sol();
    scrie();
}