Cod sursa(job #1106646)

Utilizator dunhillLotus Plant dunhill Data 12 februarie 2014 23:08:23
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#include <algorithm>
using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

#define nmax 100001
#define mod 666013

#define L (node << 1)
#define R (L | 1)

int i, j, t, n;
int cnt, ans;
int dr;

int v[nmax];
int N[nmax];
int T[nmax];
int dp[nmax];

struct nod {
	int u;
	int k;
	nod *next;
};
nod *h[mod + 3];

inline void add(int i, int j, int l) {
	nod *p = new nod;
	p->u = i;
	p->k = l;
	p->next = h[j];
	h[j] = p;
}

inline int search(int x) {
	int a = x % mod;
	for (nod *it = h[a]; it; it = it->next) 
		if (it->u == x) return it->k;
	return 0;
}

int H[3 * nmax];

inline void update(int node, int l, int r, int p, int v) {
	if (l == r){H[node] = v; return;}
	int m = (l + r) >> 1;
	if (p <= m) update(L, l, m, p, v);
	else 
		update(R, m + 1, r, p, v);
	if (dp[H[L]] > dp[H[R]]) H[node] = H[L];
	else 
		H[node] = H[R];
}

inline void query(int node, int l, int r, int i, int j) {
	if (i <= l && r <= j) {
		if (dp[H[node]] > dp[t]) 
			t = H[node];
		return;
	}
	int m = (l + r) >> 1;
	if (i <= m) query(L, l, m, i, j);
	if (j > m) query(R, m + 1, r, i, j);
}

void Print(int i) {
	if (!i) return;
	Print(T[i]);
	fout << v[i] << ' ';
}

int main() {
	fin >> n;
	for (i = 1; i <= n; ++i) fin >> v[i], N[i] = v[i];
	sort(N + 1, N + n + 1);
	for (i = 1; i <= n; ++i) {
		if (N[i] == N[i - 1]) add(N[i], N[i] % mod, cnt);
		else 
			add(N[i], N[i] % mod, ++cnt);
	}
	for (i = 1; i <= n; ++i) N[i] = search(v[i]);
	dp[1] = 1;
	update(1, 1, cnt, N[1], 1);
	for (i = 2; i <= n; ++i) {
		t = 0;
		if (N[i] - 1)
			query(1, 1, cnt, 1, N[i] - 1);
		dp[i] = dp[t] + 1;
		T[i] = t;
		update(1, 1, cnt, N[i], i);
		if (dp[i] > ans) 
			ans = dp[i], dr = i;
	}
	fout << ans << '\n';
	Print(dr);
	return 0;
}