Cod sursa(job #1605629)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 19 februarie 2016 11:54:07
Problema Subsir crescator maximal Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 100000;

int n; int m;

int v[NMAX + 1];

vector<int> uniq;

int aib[NMAX + 1]; //aib[i] = cel mai mare element din intervalul v[i] ... v[i] - 2^(nr primului bit de i al lui i(incepand de la 0)) + 1, inclusiv

int ind[NMAX + 1]; //ind[i] = pozitia pe care s-ar afla al i-lea element daca vectorul ar fi sortat

int best[NMAX + 1];

int before[NMAX + 1]; int lastIndex;

vector<int> sol;

void read() {

	fin >> n; 
	
	for(int i = 1; i <= n ; ++i) {
		fin >> v[i]; ind[i] = i;
		uniq.push_back(v[i]);
	}
}

void prepare() {

	sort(uniq.begin(), uniq.end());
	
	uniq.erase( unique( uniq.begin(), uniq.end() ) , uniq.end() );

	for(int i = 1; i <= n; ++i)
		ind[i] = lower_bound(uniq.begin(), uniq.end(), v[i]) - uniq.begin() + 1;

	m = uniq.size();
}

int lastBit(int x) {

	return x & (-x);
}

void insertAib(int pos, int val) {

	//in aib tinem elementele sortare, cand interogam pentru best[i], interogam 
	// 1...i, unde stim sigur ca elementele v[j] < v[i], cu j < i

	for( ; pos <= m ; pos += lastBit(pos) ) 
		if(aib[pos] < val)
			aib[pos] = val;
}

int interogateAib(int pos) { //cel mai mare element din intervalul 1...x

	int bestI = 0;

	for( ; pos ; pos -= lastBit(pos)) 
		if(bestI < aib[pos])
			bestI = aib[pos];

	return bestI;
}

void solve() {

	int maxSol = 0;

	prepare();

	for(int i = 1; i <= n; ++i) {

		int bes = 1 + interogateAib(ind[i] - 1);

		insertAib(ind[i], bes);

		if(maxSol < bes) maxSol = bes;
	}

	fout << maxSol << '\n';
}

int main() {

	read();

	solve();

	return 0;
}