Cod sursa(job #2245090)

Utilizator DRLDRLRaul Ronald Galea DRLDRL Data 24 septembrie 2018 18:21:51
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.49 kb
#pragma once

#include<iostream>
#include<fstream>
#include<algorithm>
#include<vector>

using namespace std;

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


#define N 1000001

int Aint[4 * N], sol, n, best = -1, pozBest = -1;
vector<pair<int, int>> indexes, leaves;
vector<int> lis, elem, noDuplicates;


bool sortbysec(const pair<int, int> &a,
	const pair<int, int> &b)
{
	return (a.second < b.second);
}

void build(int nod, int st, int dr) {
	// all zero
}

void update(int nod, int st, int dr, int uS, int uD, int val) {
	if (uS <= st && uD >= dr) {
		Aint[nod] = val;
		return;
	}
	int mid = st + (dr - st) / 2;
	if (uS <= mid)
		update(2 * nod, st, mid, uS, uD, val);
	if (uD > mid)
		update(2 * nod + 1, mid + 1, dr, uS, uD, val);

	Aint[nod] = max(Aint[2 * nod], Aint[2 * nod + 1]);

}

void query(int nod, int st, int dr, int qS, int qD) {
	if (qS <= st && qD >= dr) {
		if (Aint[nod] > sol) {
			sol = Aint[nod];
		}
		return;
	}
	int mid = st + (dr - st) / 2;
	if (qS <= mid)
		query(2 * nod, st, mid, qS, qD);
	if (qD > mid)
		query(2 * nod + 1, mid + 1, dr, qS, qD);
}

void step(int i) {
	if (i + 1 < indexes.size()) {
			sol = 0; // cate in stanga

			if (indexes[i].first > 0)
				query(1, 0, n - 1, 0, indexes[i].first - 1);

			if (sol > best) {
				best = sol;
				pozBest = indexes[i].first;
			}

			leaves[indexes[i].first] = make_pair(indexes[i].second, sol);

			update(1, 0, n - 1, indexes[i].first, indexes[i].first, sol + 1);
	}
	else {
		sol = 0;

		if (indexes[i].first > 0)
			query(1, 0, n - 1, 0, indexes[i].first - 1);

		if (sol > best) {
			best = sol;
			pozBest = indexes[i].first;
		}

		leaves[indexes[i].first] = make_pair(indexes[i].second, sol);

		update(1, 0, n - 1, indexes[i].first, indexes[i].first, sol + 1);
	}
}

int main() {

	fin >> n;
	elem.resize(n);
	leaves.resize(n);
	for (int i = 0; i < n; i++) 
		fin >> elem[i];

	for (int i = 0; i < elem.size(); ++i) {
		indexes.push_back(make_pair(i, elem[i]));
	}
	sort(indexes.begin(), indexes.end(), sortbysec);

	for (int i = 0; i < indexes.size(); i++)
		step(i);

	while (best+1) {
		lis.push_back(leaves[pozBest].first);
		best--;
		pozBest--;
		if (pozBest < 0)
			break;

		while (leaves[pozBest].second != best && best>-1)
			pozBest--;
	}
	lis.erase(unique(lis.begin(), lis.end()), lis.end());
	fout << lis.size() << "\n";
	for (int i = lis.size() - 1; i >= 0; i--)
		fout << lis[i] << " ";
	return 0;
}