Cod sursa(job #553451)

Utilizator mathboyDragos-Alin Rotaru mathboy Data 14 martie 2011 08:10:22
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#define DIM2 100050
#define maxn 100050
#define mid ((st + dr) >> 1)
#define fs (mid << 1)
#define fd ((mid<<1)+1)
#define f first
#define s second
using namespace std;
vector <pair <int, int> > A;
int D[maxn], h, res, ind, C[maxn], k, N, arb[4 * maxn], sol[4 * maxn], B[maxn], up[maxn];
int lst[maxn];
char vec[DIM2];
int poz;
inline void cit(int &x)   
{   
  x=0;   
  while(vec[poz]<'0' || vec[poz]>'9')   
       if(++poz==DIM2) fread(vec,1,DIM2,stdin),poz=0;   
  
    while(vec[poz]>='0' && vec[poz]<='9')   
    {   
        x=x*10+vec[poz]-'0';   
        if(++poz==DIM2) fread(vec, 1, DIM2, stdin),poz=0;   
    }  
}   
inline void update (int nod, int st, int dr, int val, int nr, int poz)
{
	if (st == dr) {
		if (arb[nod] < nr) {
			arb[nod] = nr;
			sol[nod] = poz;
		}	
		return ;
	}
	
	if (val <= mid)
		update (fs, st, mid, val, nr, poz);
	if (val > mid)
		update (fd, mid + 1, dr, val, nr, poz);
	if (arb[fs] > arb[fd]) sol[nod] = sol[fs];
	else sol[nod] = sol[fd];
	
	arb[nod] = max (arb[fs], arb[fd]);
}
inline void query (int nod, int st, int dr, int b)
{
	if (b >= dr) {
		if (res < arb[nod]) {
			res = arb[nod];
			ind = sol[nod];
		}
		return ;
	}
	query (fs, st, mid, b);
	if (b > mid) query (fd, mid + 1, dr, b);
}

int main ()
{

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

	scanf ("%d\n", &N);
	
	int i, ord;
	int a;
	for (i = 1; i <= N; i++)
	{
		cit (a);
		A.push_back (make_pair (a, i));
		C[i] = a;
	}
	sort (A.begin (), A.end ());
	k = 1;
	B[A[0].s] = k;
	int mx, pz;
	mx = pz = 0;
	for (int i = 1; i < N; i++)
		if (A[i].f == A[i - 1].f)
			B[A[i].s] = k;
		else B[A[i].s] = ++k;
	for (i = 1; i <= N; i++) {

		res = 0;
		ind = 0;
		ord = B[i];
		if (ord - 1)
			query (1, 1, k, ord - 1);
		
		D[i] = res + 1;
		up[i] = ind;
		if (mx < D[i])
			mx = D[i], pz = i;	
		update (1, 1, k, ord, D[i], i);
	}
	
	printf ("%d\n", mx);	
	
	for (i = pz; i ; i = up[i])
		lst[++h] = C[i];
	for (; h >= 1; h--)
		printf ("%d ", lst[h]);

	return 0;
}