Cod sursa(job #1437428)

Utilizator romircea2010FMI Trifan Mircea Mihai romircea2010 Data 17 mai 2015 18:33:21
Problema Subsir crescator maximal Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

struct numar
{
    int x, newx, poz;
    numar()
    {

    }
    numar (const int &x, const int &newx, const int &poz)
    {
        this -> x = x;
        this -> newx = newx;
        this -> poz = poz;
    }
    bool operator < (const numar & other) const
    {
        return this -> x < other.x;
    }
};
struct AIB
{
    int dp, p;
};
const int NMax = 100010;
numar a[NMax], b[NMax];
int dp[NMax], pred[NMax];
AIB aib[NMax];
int N;

void Read()
{
    ifstream f ("scmax.in");
    f >> N;
    for (int i = 1; i <= N; ++ i)
    {
        int x; f >> x;
        a[i] = numar(x, 0, i);
    }
    f.close();
}

int Query(int poz, int & p)
{
    if (poz == 0)
        return 0;
    int ret = 0;
    for (; poz > 0; poz -= (poz & -poz))
    {
        if (aib[poz].dp > ret)
        {
            ret = aib[poz].dp;
            p = aib[poz].p;
        }
    }
    return ret;
}

void Update(int poz, const int & val)
{
    int from = poz;
    for (; poz <= a[N].newx; poz += (poz & -poz))
    {
        if (val > aib[poz].dp)
        {
            aib[poz].dp = val;
            aib[poz].p = from;
        }
    }
}

void Solve()
{
    sort(a+1, a+N+1);
    for (int i = 1; i <= N; ++ i)
    {
        a[i].newx = a[i-1].newx + (a[i].x != a[i-1].x ? 1 : 0);
    }
    for (int i = 1; i <= N; ++ i)
    {
        b[a[i].poz] = a[i];
    }
    for (int i = 1; i <= N; ++ i)
        a[i] = b[i];
    for (int i = 1; i <= N; ++ i)
    {
        int p = -1;
        dp[a[i].newx] = 1 + Query(a[i].newx - 1, p);
        pred[a[i].newx] = p;
        Update(a[i].newx, dp[a[i].newx]);
    }
}

void Write()
{
    int maxim = 0, poz;
    for(int i = 1; i <= N; ++ i)
    {
        if (dp[a[i].newx] > maxim)
        {
            maxim = dp[a[i].newx];
            poz = a[i].newx;
        }
    }
    ofstream g("scmax.out");
    g << maxim << "\n";
    vector <int> ans;
    while (pred[poz] != -1)
    {
        ans.push_back(poz);
        poz = pred[poz];
    }
    ans.push_back(poz);
    reverse(ans.begin(), ans.end());
    int i = 0;
    for (vector <int> :: iterator it = ans.begin(); it != ans.end(); ++ it)
    {
        for (++ i; *it != a[i].newx; ++ i);
        g << a[i].x << " ";
    }
    g << "\n";
    g.close();

}

int main()
{
    Read();
    Solve();
    Write();
    return 0;
}