Cod sursa(job #1751302)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 1 septembrie 2016 10:15:49
Problema Subsir crescator maximal Scor 55
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
#include <fstream>
#include <string.h>
#include <limits.h>
#include <stack>

#define MAX_DIM_TREE 262150 // 2^18 - 1
#define MAX_DIM_VECT 100002
using namespace std;

typedef struct node
{
	int val;
	int pos;
	struct node *next;
}Node;

void Initialise(int n, int &treeDim, int *tree, Node **parentVect);
void Process(int n, int treeDim, int &max, int* tree, Node** parentVect, istream &fin);
int Update (int pos, int x, int treeDim, int* tree, Node** parentVect);
void WriteResult(int max, Node** parentVect, ostream &fout);

int main()
{
	int treeDim;
	int tree[MAX_DIM_TREE];
	Node* parentVect[MAX_DIM_VECT];
	int n, max;

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

	Initialise(n, treeDim, tree, parentVect);

	Process(n, treeDim, max, tree, parentVect, fin);

	WriteResult(max, parentVect, fout);

	fin.close();
	fout.close();
	return 0;
}

void Initialise(int n, int &treeDim, int *tree, Node **parentVect)
{
	treeDim = 1;
	int exp = 1;
	while(exp < n)
	{
		exp *= 2;
		treeDim += exp;
	}

	for(int i = 1; i <= treeDim +1; i++)
	{
		tree[i] = INT_MAX;
	}
	memset(parentVect, 0, MAX_DIM_VECT * sizeof(Node*));
}

void Process (int n, int treeDim, int &max, int* tree, Node **parentVect, istream &fin)
{
	int x;
	for(int i = 0; i < n; ++i)
	{
		fin >> x;
		int pos = Update(1, x, treeDim, tree, parentVect);

		if(pos != 0)
		{
			Node* newNode = new Node();
			newNode->pos = pos;
			newNode->val = x;
			newNode->next = parentVect[pos];
			parentVect[pos] = newNode;

			if(pos > max)
			{
				max = pos;
			}
		}

	}
}

int Update (int pos, int x, int treeDim, int* tree, Node **parentVect)
{
	if(2 * pos > treeDim && x < tree[pos])
	{
		tree[pos] = x;

		return pos - treeDim / 2;
	}

	if(tree[2 * pos] >= x)
	{
		return Update(2 * pos, x, treeDim, tree, parentVect);
	}
	else if (tree [2 * pos + 1] > x)
	{
		int result = Update(2 * pos + 1, x, treeDim, tree, parentVect);
		tree[pos] = tree[2 * pos + 1];

		return result;
	}

	return 0;
}

void WriteResult(int max, Node** parentVect, ostream &fout)
{
	stack<Node*> result;

	fout << max << "\n";

	Node* prev = parentVect[max];
	result.push(prev);

	for(int i = max - 1; i > 0; --i)
	{
		Node* current = parentVect[i];
		Node* selected = NULL;

		while(current != NULL)
		{
			if(current->pos < prev->pos && current->val < prev->val &&(selected == NULL || current->val < selected->val))
			{
				selected = current;
			}

			current = current->next;
		}

		prev = selected;
		result.push(prev);
	}

	while(!result.empty())
	{
		fout << result.top()->val << " ";
		result.pop();
	}
}