Cod sursa(job #2460177)

Utilizator Johnny07Savu Ioan-Daniel Johnny07 Data 22 septembrie 2019 23:26:23
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream f("scmax.in");
ofstream g("scmax.out");
ifstream ff("test10.ok");

int n;
int tree[1700000];
int dp[100010];

struct number
{
	int initial_value, normalized_value, position;
}a[100001];


bool comp_value(number a, number b)
{
	return (a.initial_value < b.initial_value);

}


bool comp_position(number a, number b)
{
	return (a.position < b.position);
}


void read()
{
	f >> n;
	for (int i = 1; i <= n; i++)
	{
		f >> a[i].initial_value;
		a[i].position = i;
		a[i].normalized_value = 1;
	}


}


void normalize()
{

	int i, j;
	sort(a + 1, a + n + 1, comp_value);
	for (i = 2; i <= n; i++)
	{
		if (a[i].initial_value == a[i - 1].initial_value)
			a[i].normalized_value = a[i - 1].normalized_value;
		else a[i].normalized_value = a[i - 1].normalized_value + 1;

	}
	sort(a + 1, a + n + 1, comp_position);

}


int search_in_tree(int value,int left,int right,int index)
{
	if (left < right)
	{
		if (value > right) return tree[index];
		int mid = left + right;
		mid /= 2;
		if (value <= mid) return (search_in_tree(value, left, mid, 2 * index));
		else return (max(search_in_tree(value, left, mid, 2 * index), search_in_tree(value, mid + 1, right, 2 * index + 1)));
	}
	else
	{
		if (value > right) return tree[index];
		return 0;
	}
}

void update(int value, int left, int right, int index, int ma)
{
	int mid = left + right;
	mid /= 2;
	if (left < right)
	{
		if (value > mid) update(value, mid + 1, right, 2 * index + 1, ma);
		else update(value, left, mid, 2 * index, ma);

		tree[index] = max(tree[2 * index], tree[2 * index + 1]);
	}
	else
	{
		tree[index] = max(tree[index], ma);
	}


}

void solve()
{
	int i,ma=0;	
	for (i = 1; i <= n; i++)
	{
		ma=search_in_tree(a[i].normalized_value, 1, n, 1);
		ma++;
		update(a[i].normalized_value, 1, n, 1, ma);
		dp[i] = ma;
	}
	ma = 0;
	int poz;
	for (i = 1; i <= n; i++)
	{
		if (dp[i] > ma) { ma = dp[i]; poz = i; }
	}
	g << ma<<endl;
}


void display()
{
	int i, ma = 0, poz, sol[100010];
	for (i = 1; i <= n; i++)
	{
		if (dp[i] > ma)
		{
			ma = dp[i];
			poz = i;
		}
	}int nr = 1;
	sol[nr] = a[poz].initial_value;
	for (i = poz-1; i >= 1; i--)
	{
		if ( (dp[i] == dp[poz] - 1 ) && (a[i].initial_value < a[poz].initial_value))
		{
			nr++;
			sol[nr] = a[i].initial_value;
			poz = i;
		}
	}


	for (i = nr; i >= 1; i--)
	{
		g << sol[i] << " ";
	}


}

int main()
{

	read();
	normalize();
	solve();
	display();

	return 0;
}