Cod sursa(job #997854)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 14 septembrie 2013 23:19:14
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;

const string file = "scmax";

const string infile = file + ".in";
const string outfile = file + ".out";

const int INF = 0x3f3f3f3f;


vector<int> DP;


class AibMax
{
public:

	static int zeros(int x)
	{
		return (x ^ ( x -1)) & x;
	}

	AibMax(int size)
	{
		this->_size = size;
		this->_data.resize(_size + 1);
	}

	void Update(int x, int v)
	{
		for(int i = x; i <= _size; i += zeros(i))
		{
			if(DP[_data[i]] < DP[v])
				_data[i] = v;
		}
	}

	int Query(int x)
	{
		int r = 0;
		for(int i = x; i > 0; i -= zeros(i))
		{
			if(DP[_data[i]] > DP[r])
				r = _data[i];
		}
		return r;
	}
protected:
private:
	int _size;
	vector<int> _data;
};

vector<int> A;
vector<int> B;
vector<int> D;
vector<int> Prec;
int N;

bool pred(int a, int b)
{
	return A[a] < A[b];
}

void printSol(ostream& fout, int i )
{
	if(i == 0)
		return;

	printSol(fout, Prec[i]);
	fout << A[i] << " ";
}

int main()
{
	fstream fin(infile.c_str(), ios::in);
	fin >> N;
	
	A.resize(N + 1);
	B.resize(N + 1);
	DP.resize(N + 1);
	D.resize(N + 1);
	Prec.resize(N + 1);


	for(int i = 1; i <= N; i++)
	{
		fin >> A[i];
		B[i] = i;
	}
	fin.close();

	sort(B.begin() + 1, B.end(), pred);

	int contor = 1;
	for(int i = 1; i <= N; i++)
	{
		if(A[B[i]] == A[B[i-1]])
		{
			D[B[i]] = D[B[i-1]];
		}
		else
		{
			D[B[i]] = contor++;
		}
	}
	
	AibMax aib(contor);

	int maxI = 0;
	int Sol = 0;
	for(int i = 1; i <= N; i++)
	{
		int q = aib.Query(D[i] - 1);
		DP[i] = DP[q] + 1;
		Prec[i] = q;
		aib.Update(D[i], i);
		if(DP[i] > Sol)
		{
			Sol = DP[i];
			maxI = i;
		}
	}

	fstream fout(outfile.c_str(), ios::out);
	fout << Sol << "\n";
	printSol(fout, maxI);
	fout << "\n";
	fout.close();
}