Cod sursa(job #447222)

Utilizator dcm9000Dinu Cristian Mircea - UPB dcm9000 Data 28 aprilie 2010 00:46:43
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>

using namespace std;

#define FILE_IN "scmax.in"
#define FILE_OUT "scmax.out"

typedef unsigned int uint;

#define NONE N

int N;
int* aib;
uint* sir;
uint* compact;
int* lung;
int* pre;

void aib_setmax(int index, int value)
{
    while (index <= N)
    {
        if (lung[value] > lung[aib[index]])
            aib[index] = value;

        index += (index & -index);
    }
}

int aib_getmax(int index)
{
    int best = NONE;

    while (index)
    {
        if (lung[aib[index]] > lung[best])
            best = aib[index];

        index &= (index-1);
    }

    return best;
}

int main()
{
    ifstream fisIn(FILE_IN);
    ofstream fisOut(FILE_OUT);

    fisIn >> N;

    sir = new uint[N];
    for (int i=0; i<N; i++) fisIn >> sir[i];

    compact = new uint[N];
    copy(sir, sir+N, compact);
    sort(compact, compact+N);
    for (int i=0; i<N; i++)
        sir[i] = 1+(lower_bound(compact, compact+N, sir[i])-compact);

    lung = new int[N+1];
    pre = new int[N+1];
    lung[NONE] = 0;
    pre[NONE] = -1;

    aib = new int[N+1];
    fill(aib, aib+N+1, NONE);

    for (int i=0; i<N; i++)
    {
        int best = aib_getmax(sir[i]-1);

        lung[i] = lung[best]+1;
        pre[i] = best;

        aib_setmax(sir[i], i);
    }

    int best = aib_getmax(N);

    int lungime = lung[best];
    uint* rez = new uint[lungime];

    uint* ptr = rez+lungime-1;
    while (best != NONE)
    {
        *(ptr--) = compact[sir[best]-1];
        best = pre[best];
    }

    fisOut << lungime << "\n";
    for (int i=0; i<lungime; i++)
    {
        if (i) fisOut << ' ';
        fisOut << rez[i];
    }
    fisOut << '\n';
}