Cod sursa(job #2574015)

Utilizator WladDalwMvladutu cristian vlad WladDalwM Data 5 martie 2020 19:58:21
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
#include <fstream>
#include <algorithm>
#include <stdio.h>
#include <ctype.h>

using namespace std;

ofstream out("scmax.out");

int aib[100005];
int d[100005];
int r[100005];
int n;

FILE *_fin;
int _in_loc; char _in_buff[4096];


void read_init(const char* nume)
{
    _fin = fopen(nume, "r");
    _in_loc = 4095;
}

char read_ch()
{
    ++_in_loc;
    if (_in_loc == 4096) {
        _in_loc = 0;
        fread(_in_buff, 1, 4096, _fin);
    }
    return _in_buff[_in_loc];
}

int read_u32()
{
    int u32 = 0; char c;
    while (!isdigit(c = read_ch()) && c != '-');
    int sgn = 1;
    if (c == '-') {
        sgn = -1;
    } else {
        u32 = c - '0';
    }
    while (isdigit(c = read_ch())) {
        u32 = u32 * 10 + c - '0';
    }
    return u32 * sgn;
}

struct no
{
    int val , poz, no;
}v[100005];

int len(int x)
{
    return x & -x;
}

int q(int poz)
{
    int maxim = 0;
    while(poz)
    {
        maxim = max(maxim , aib[poz]);
        poz -= len(poz);
    }
    return maxim;
}

int u(int poz , int val)
{

    while(poz <= n)
    {
        aib[poz] = max(aib[poz] , val);
        poz += len(poz);
    }
}

bool xort1(no a , no b)
{
    if(a.val < b.val)
        return true;
    return false;
}

void nor()
{
    int ac = 0;
    v[0].val = -1;
    for(int i = 1; i <= n; i++)
        {ac += (v[i - 1].val != v[i].val);
        v[i].no = ac;}
}

bool xort2(no a , no b)
{
    if(a.poz < b.poz)
        return true;
    return false;
}

int main()
{

    int i , best = 0 , rez , last;
    read_init("scmax.in");
    n = read_u32();
    for(i = 1; i <= n; i++)
    {
        v[i].val = read_u32();;
        v[i].poz = i;
    }

    sort( v + 1, v + n + 1, xort1);
    nor();
    sort(v + 1, v + n + 1, xort2);

    for(i = 1; i <= n; i++)
    {
        d[i] = q(v[i].no - 1) + 1;
        best = max(best , d[i]);
        u(v[i].no , d[i]);
    }
    out << best << '\n';
    rez = best;
    last = 0;
    v[last].val = 2000000005;
    for(i = n; i >= 1 && best; i--)
    {
        if(d[i] == best && v[i].val < v[last].val)
            r[best--] = v[i].val , last = i;
    }
    for(i = 1; i <= rez; i++)
        out << r[i] << " ";

    return 0;
}