Cod sursa(job #997849)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 14 septembrie 2013 23:11:08
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 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<pair<int, int> > C;
vector<int> D;
vector<int> Prec;
int N;



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);
	C.resize(N + 1);
	D.resize(N + 1);
	Prec.resize(N + 1);


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

	sort(C.begin() + 1, C.end());

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

	for(int i = 1; i <= N; i++)
	{
		B[C[i].second] = D[i];
	}
	int maxI = 0;
	int Sol = 0;
	for(int i = 1; i <= N; i++)
	{
		int q = aib.Query(B[i] - 1);
		DP[i] = DP[q] + 1;
		Prec[i] = q;
		aib.Update(B[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();
}