Cod sursa(job #999565)

Utilizator sunt_emoSunt emo sunt_emo Data 20 septembrie 2013 19:56:45
Problema Subsir crescator maximal Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <fstream>
#include <algorithm>

#define N 100010

using namespace std;

int data[N];
pair<int, int> data2[N];
int best[N];
int ord[N];
int aib[N];
int pred[N];
int n;

bool comp(const pair<int, int> &a, const pair<int, int> &b)
{
    return a.first < b.first;
}

void update(int ind)
{
    int it = 1;
    while (it < n)
    {
        if (best[aib[ind]] >= best[aib[ind | it]])
            aib[ind | it] = ind;
        it = (it << 1) + 1;
    }
}

int maximum(int ind)
{
    int it = ind + 1, res = ind;

    while (it)
    {
        if (best[aib[it - 1]] > best[aib[res]])
            res = aib[it - 1];
        it &= it - 1;
    }

    return res;
}

void read(const char *filename)
{
    ifstream in(filename);
    in >> n;
    for (int i = 0; i < n; i++)
        in >> data[i];
    in.close();
}

void write(const char *filename)
{
    ofstream out(filename);

    int it = 0;

    for (int i = 1; i < n; i++)
        if (best[i] > best[it])
            it = i;
        else if (best[i] == best[it] && data2[i].first > data2[it].first)
            it = i;

    //int it = ord[n - 1];
    int res[N];
    int pos = 0;
    while (best[it]--)
    {
        if (pos > 0)
            if (data2[it].first == res[pos - 1])
            {
                it = pred[it];
                continue;
            }
        res[pos++] = data2[it].first;
        it = pred[it];
    }
    out << pos << endl;
    while (pos--)
        out << res[pos] << " ";
    out << endl;
    out.close();
}

void prepare()
{
    for (int i = 0; i < n; i++)
    {
        data2[i] = make_pair(data[i], i);
        best[i] = 0;
        aib[i] = i;
    }

    sort(data2, data2 + n, comp);

    for (int i = 0; i < n; i++)
        ord[data2[i].second] = i;
}

void algo()
{
    best[ord[0]] = 1;
    pred[ord[0]] = -1;
    update(ord[0]);

    for (int i = 1; i < n; i++)
    {
        int res = maximum(ord[i]);
        best[ord[i]] = best[aib[res]] + 1;
        pred[ord[i]] = aib[res];
        update(ord[i]);
    }
}

int main()
{
    read("scmax.in");
    prepare();
    algo();
    write("scmax.out");
}