Cod sursa(job #583098)

Utilizator varuvasiTofan Vasile varuvasi Data 17 aprilie 2011 23:27:46
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>

#define maxn 100033

using namespace std;

int N, max_value;
int arb[maxn*4], A[maxn], v[maxn], norm[maxn], previous[maxn], d[maxn];

void update_tree(int node, int st, int dr, int a, int index)
{
	if (a == st && a == dr)
	{
		arb[node] = index;
		return;
	}
	int mij = (st+dr)/2;
	if (a <= mij)
		update_tree(node*2, st, mij, a, index);
	if (a > mij)
		update_tree(node*2+1, mij+1, dr, a, index);
	arb[node] = (d[arb[node*2]] > d[arb[node*2+1]]) ? arb[node*2] : arb[node*2+1];
}

void query_tree(int node, int st, int dr, int a, int b)
{
	if (a <= st && b >= dr)
	{
		max_value = (d[arb[node]] > d[max_value]) ? arb[node] : max_value;
		return;
	}
	int mij=(st+dr)/2;
	if (a <= mij)
		query_tree(node*2, st, mij, a, b);
	if (b > mij)
		query_tree(node*2+1, mij+1, dr, a, b);
}

int main()
{
	int i=0, h=0;
	FILE *fin = fopen("scmax.in", "rt"), *fout = fopen("scmax.out", "wt");

	fscanf(fin, "%d", &N);
	for (i=0; i<N; i++)
	{
		fscanf(fin, "%d", &A[i]);
		v[i] = A[i];
	}

	sort(A, A+N);
	for (i=1; i<N; i++)
		if (A[i] != A[h])
			A[++h] = A[i];
	for (i=0; i<N; i++)
		norm[i+1] = lower_bound(A, A+h, v[i]) - A + 1;

	/*for (i=0; i<N; i++)
		fprintf(fout, "%d ", A[i]);
	fprintf(fout, "\n");
	for (i=1; i<=N; i++)
		fprintf(fout, "%d ", norm[i]);*/

	int k=0, best=0;
	// d indexed from 1, same as norm
	for (i=1; i<=N; i++)
	{
		max_value = 0;
		if (norm[i] != 1)
			query_tree(1, 1, N, 1, norm[i] - 1);
		if (!max_value)
		{
			d[i] = 1;
			update_tree(1, 1, N, norm[i], i);
		}
		else
		{
			previous[i] = max_value;
			d[i] = d[max_value] + 1;
			update_tree(1, 1, N, norm[i], i);
		}
		if (d[i] > d[best])
			best = i;
	}

	/*fprintf(fout, "\n");
	for (i=1; i<=N; i++)
		fprintf(fout, "%d ", d[i]);
	fprintf(fout, "\n");*/
	h=0;
	fprintf(fout, "%d\n", d[best]);
	for (; best != 0; best = previous[best])
		norm[++h] = v[best-1];
	for (i=h; i>0; --i)
		fprintf(fout, "%d ", norm[i]);

	fclose(fin), fclose(fout);
	return 0;
}