Cod sursa(job #222077)

Utilizator devilkindSavin Tiberiu devilkind Data 19 noiembrie 2008 22:56:05
Problema Subsir crescator maximal Scor 45
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <stdio.h>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

#define NMAX 100002
#define mp make_pair
#define ff first
#define ss second
#define CMAX 1002000

int A[NMAX];
int V[NMAX];
pair<int, int> ARB[3 * NMAX];
map<int, int> H;
int din[NMAX];
int prec[NMAX];
pair<int, int> ret;
int sol[NMAX];
int N;
char S[CMAX];

void update(int nod, int st, int dr, int poz, int val, int p)
{
	if (st == dr) ARB[nod] = max(ARB[nod], mp(val, p));
		else
		{
			int mid = (st + dr) / 2;

			if (mid >= poz) update(nod * 2, st, mid, poz, val, p);
				else update(nod * 2 + 1, mid + 1, dr, poz, val, p);

			ARB[nod] = max(ARB[nod * 2], ARB[nod * 2 + 1]);
		}
}

void query(int nod, int st, int dr, int a, int b)
{
	if (a <= st && dr <= b) ret = max(ret, ARB[nod]);
		else 
		{
			int mid = (st + dr) / 2;

			if (a <= mid) query(nod * 2, st, mid, a, b);
			if (b > mid) query(nod * 2 + 1, mid + 1, dr, a, b);
		}
}



int main()
{
	freopen("scmax.in", "r", stdin);
	freopen("scmax.out", "w", stdout);

	int i;
	scanf("%d\n", &N);
	
/*	for (i = 1; i <= N; i++)
		{
			scanf("%d ", &A[i]);
			V[i] = A[i];
		}*/

        fgets(S, CMAX, stdin);

        int x = 0, j;
        for (j = 0, i = 1; S[j] != '\n'; j++)
                if (S[j] == ' ') {
                        A[i++] = x;
                        x = 0;
                        }
                        else x = x * 10 + S[j] - '0';
        if (x) A[N] = x;
        for (i = 1; i <= N; i++) V[i] = A[i];

	sort(V+1, V+N+1);

	for (i = 1; i <= N; i++)
		if (!H[ V[i] ]) H[ V[i] ] = i;

	for (i = 1; i <= N; i++)
		A[i] = H[ A[i] ];

	update(1, 1, N, A[1], 1, 1);
	din[1] = 1;
	prec[1] = 0;
	int L, P;
	L = 1; P = 1;

	for (i = 2; i <= N; i++)
	{
		if (A[i] == 1) {
			din[i] = 1;
			prec[i] = 1;
        		update(1, 1, N, A[i], din[i], i);
                        continue;
		}

		ret = mp(0, 0);
		query(1, 1, N, 1, A[i] - 1);
		
		din[i] = ret.ff + 1;
		prec[i] = ret.ss;
		if (din[i] > L) 
		{
			L = din[i];
			P = i;
		}

		update(1, 1, N, A[i], din[i], i);
	}

	printf("%d\n", L);

	for (i = L; i; i--)
	{
		sol[i] = A[P];
		P = prec[P];
	}

	for (i = 1; i <= L; i++) printf("%d ", V[ sol[i] ]);

	return 0;
}