Cod sursa(job #2104939)

Utilizator cristicretancristi cretan cristicretan Data 12 ianuarie 2018 13:51:40
Problema Subsir crescator maximal Scor 80
Compilator cpp Status done
Runda arhivacre Marime 1.81 kb
/// LONGEST INCREASING SUBSEQUENCE
#include <iostream>
#include <fstream>
#include <utility>
#include <algorithm>
#include <map>
#include <sstream>
#include <memory>
#include <cstring>
#define NMax 100001
///#define f cin
///#define g cout
using namespace std;

ifstream f("scmax.in");
ofstream g("scmax.out");

int n, a[NMax], temp[NMax], sol[NMax], ans, realSol[NMax], foo;

int topmiddle(int a[NMax], int temp[NMax], int end, int key)
{
    int start = 0;
    int middle;
    int len = end;
    while(start <= end)
    {
        middle = (start + end) / 2;
        if(a[temp[middle]] < key && key <= a[temp[middle + 1]]) return middle + 1; /// daca cheia e intre a de mijlocul lui T si mijlocul lui T + 1 returnezi mijlocul + 1
        else if(a[temp[middle]] < key) start = middle + 1; /// altfel continui binary search..
        else end = middle - 1;
    }
    return -1;
}

int main()
{
    f >> n;
    for(int i = 1; i <= n; ++i)
    {
        f >> a[i];
        sol[i] = -1;
    }

    for(int i = 1; i <= n; ++i)
    {
        if(a[temp[1]] > a[i]) temp[1] = i;
        else if(a[temp[ans]] < a[i]) /// daca a[i] e mai mare decat ultima valoare din T atunci o bagi a ultima valoare in T
        {
            ++ans;
            temp[ans] = i;
            sol[temp[ans]] = temp[ans - 1];
        }
        else /// faci binary search sa gasesti maximul din elementele din mijloc
        {
            int index = topmiddle(a, temp, ans, a[i]);
            temp[index] = i;
            sol[temp[index]] = temp[index - 1];
        }
    }

    g << ans << '\n';

    int index = temp[ans];
    while(index != -1)
    {
        realSol[++foo] = a[index];
        index = sol[index];
    }
    for(int i = foo; i >= 1; --i)
        g << realSol[i] << " ";

    return 0;
}