Cod sursa(job #1005417)

Utilizator sunt_emoSunt emo sunt_emo Data 5 octombrie 2013 00:43:01
Problema Subsir crescator maximal Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include <fstream>
#include <iostream>
#include <algorithm>

#define N 100010

int n;
int data[N];
int pos[N];
int left[N];
int aib[N];
int best[N];
int pred[N];
int res[N];
std::pair<int, int> sorted[N];

int query(int p)
{
    int ret = aib[p];
    while (p)
    {
        if (best[aib[p]] > best[ret])
            ret = aib[p];
        p &= p - 1;
    }
    return ret;
}

void update(int p, int bp)
{
    while (p <= n)
    {
        if (best[aib[p]] < best[bp])
            aib[p] = bp;
        p += p & (-p);
    }
}

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

void read_data(const char *filename)
{
    std::ifstream in(filename);
    in >> n;
    for (int i = 0; i < n; ++i)
    {
        in >> data[i];
        sorted[i] = std::make_pair(data[i], i);
    }
    in.close();
}

void prepare()
{
    std::sort(sorted, sorted + n, comp);
    for (int i = 0; i < n; ++i)
        pos[sorted[i].second] = i;
    left[0] = 0;
    for (int i = 1; i < n; i++)
        if (sorted[i].first == sorted[i - 1].first)
            left[i] = left[i - 1];
        else
            left[i] = i;
    for (int i = 1; i <= n; i++)
        aib[i] = i - 1;
    for (int i = 0; i < n; ++i)
        best[i] = 0;
}

void alg()
{
    best[pos[0]] = 1;
    update(pos[0] + 1, pos[0]);
    pred[pos[0]] = -1;
    for (int i = 1; i < n; i++)
    {
        if (left[pos[i]] == 0)
        {
            best[pos[i]] = 1;
            pred[pos[i]] = -1;
        }
        else
        {
            int q = query(left[pos[i]]);
            best[pos[i]] = best[q] + 1;
            pred[pos[i]] = q;
        }
        update(pos[i] + 1, pos[i]);
    }

}

void resp(const char *filename)
{
    std::ofstream out(filename);
    int g = 0;
    for (int i = 1; i < n; i++)
        if (best[i] > best[g])
            g = i;
    std::cout << best[g] << "\n";

    n = 0;

    while (g != -1)
    {
        res[n++] = g;
        g = pred[g];
    }

    while (n--)
        std::cout << sorted[res[n]].first << " ";
    std::cout << "\n";

    out.close();
}

int main()
{
    read_data("scmax.in");
    prepare();
    alg();
    resp("scmax.out");
}