Cod sursa(job #186132)

Utilizator tvladTataranu Vlad tvlad Data 26 aprilie 2008 19:33:13
Problema Subsir crescator maximal Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

const int N = 100000;

class arb_int {
	int n, size;
	vector< pair<int,int> > v;
	void update ( int k, int s, int e, int p, int val ) {
		if (v[k].first < val) {
//			printf("Update %d(%d) - %d\n",k,p,val);
			v[k].first = val;
			v[k].second = p;
		}
		if (s != e) {
			int m = (s+e)/2;
			if (p <= m)
				update(2*k,s,m,p,val); else
				update(2*k+1,m+1,e,p,val);
		}
	}
	pair<int,int> maximum ( int k, int s, int e, int is, int ie ) {
		if (is > ie) return pair<int,int>(0,0);
//		printf("Query [%d,%d] -> [%d,%d] - %d\n",is,ie,s,e,k);
		if (s == is && e == ie) return v[k];
		int m = (s+e)/2;
		pair<int,int> a1, a2;
		if (is <= m) {
			a1 = maximum(2*k,s,m,is,min(m,ie));
			if (ie <= m) return a1;
		}
		if (ie > m) {
			a2 = maximum(2*k+1,m+1,e,max(m+1,is),ie);
			if (is > m) return a2;
		}
		return max(a1,a2);
	}
public:
	arb_int ( int x, int init = 0 ) {
		n = x;
		size = 2;
		for (int i = 1; i < x; i <<= 1, size += i);
		v.resize(size);
		for (int i = 0; i < size; ++i) v[i].first = init, v[i].second = 0;
	}
	void update ( int pos, int val ) { update(1,1,n,pos,val); }
	int maximum ( int start, int end, int &p ) {
		pair<int,int> x = maximum(1,1,n,start,end);
		p = x.second;
		return x.first;
	}
};

int n;
int a[N], d[N], p[N];

int main() {
	freopen("scmax.in","rt",stdin);
	freopen("scmax.out","wt",stdout);
	scanf("%d",&n);
	vector<int> norm(n);
	for (int i = 0; i < n; ++i) {
		scanf("%d",&a[i]);
		norm[i] = a[i];
	}
	sort(norm.begin(), norm.end());
	norm.resize(unique(norm.begin(),norm.end()) - norm.begin());
	for (int i = 0; i < n; ++i) a[i] = lower_bound(norm.begin(), norm.end(), a[i]) - norm.begin()+1;
	
	arb_int ai(n);
	d[0] = 1; p[0] = 0;
	int m = 1, pm = 0;
	ai.update(a[0],1);
	for (int i = 1; i < n; ++i) {
		d[i] = ai.maximum(1,a[i]-1,p[i]) + 1;
//		printf("%d ",p[i]);
		if (d[i] > m) {
			m = d[i];
			pm = i;
		}
		ai.update(a[i],d[i]);
	}
//	printf("\n");
	
	vector<int> sol;
	if (pm == 0) sol.push_back(norm[a[0]-1]);
	for (int k = pm; k != 0; k = p[k])
		sol.push_back(norm[a[k]-1]);
	printf("%d\n",m);
	for (int i = sol.size()-1; i >= 0; --i) printf("%d ",sol[i]);
	printf("\n");
	return 0;
}