Cod sursa(job #1207522)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 13 iulie 2014 12:24:45
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
using namespace std;
#include <fstream>
#include <algorithm>
FILE *fin = fopen("scmax.in", "r");
ofstream fout("scmax.out");
const int Nmax = 100010;

int n;
int v[Nmax], poz[Nmax], lst[Nmax], D[Nmax], AIB[Nmax], pred[Nmax];

int query(int) ;
void update(int, int) ;

int main()
{
	int i, h, bst = 0;
	fscanf(fin, "%d", &n);
	for(i = 1; i <= n; ++i)
	{
	    fscanf(fin, "%d", v + i);
	    lst[i] = v[i];
	}
	sort(lst + 1, lst + n + 1);
	
	for(i = h = 1; i <= n; ++h)
	{
	    lst[h] = lst[i];
	    while(lst[i] == lst[h]) ++i;
	}
	for(i = 1; i <= n; ++i)
        poz[i] = lower_bound(lst + 1, lst + h, v[i]) - lst;
    
    for(i = 1; i <= n; ++i)
    {
        pred[i] = query(poz[i] - 1);
        D[i] = 1 + D[pred[i]];
        if(D[i] > D[bst]) bst = i;
        update(i, poz[i]);
    }
    
    fout << D[bst] << '\n';
    for(h = 0; bst > 0; bst = pred[bst])
        lst[h++] = bst;
    for(--h; h >= 0; --h)
        fout << v[lst[h]] << ' ';
    fout << '\n';
	return 0;
}


int query(int poz)
{
    int el = 0;
    for(; poz; poz &= poz - 1)
    {
        if(D[el] < D[AIB[poz]])
            el = AIB[poz];
    }
    return el;
}


void update(int ind, int x)
{
    while(x <= n)
    {
        if(D[AIB[x]] < D[ind])
            AIB[x] = ind;
        x += x & -x;
    }
}