Cod sursa(job #999540)

Utilizator sunt_emoSunt emo sunt_emo Data 20 septembrie 2013 17:58:13
Problema Subsir crescator maximal Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 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);
    out << best[ord[n - 1]] << endl;

    int it = ord[n - 1];
    int res[N];
    int pos = 0;
    while (best[it]--)
    {
        res[pos++] = data2[it].first;
        it = pred[it];
    }
    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");
}