Cod sursa(job #648735)

Utilizator mihaibogdan10Mihai Bogdan mihaibogdan10 Data 14 decembrie 2011 04:53:49
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
#include<cstdio>
#include<vector>
FILE *in = fopen ("scmax.in", "r"), *out = fopen ("scmax.out", "w");
using namespace std;

vector <int> sir(100001), prec(100001), M(100001, 0);
/*M[i] = pozitia celui mai mic numar X = sir[M[i]] care este capatul din dreapta al unui subsir crescator de lungime i
prec[i] = predecesorul numarului sir[i] in cadrul subsirului crescator*/

void Afiseaza(int poz){
	if (prec[poz] == poz)	return;
	Afiseaza(prec[poz]);
	fprintf(out, "%d ", sir[poz]);
}

int CautaMax(int maxPoz, int maxVal)
{
	// cauta in intervalul (0, maxPoz) pozitia celui mai mare numar X < maxVal
	int st = 1, dr = maxPoz, m;
	while (st <= dr)
	{
		m = (st + dr) / 2;
		if (maxVal <= sir[M[m]]) dr = m-1;
		else st = m+1;
	}
	return st - 1;
}
int main(){
	int n, i, j, Maxim = 0, P;	
	/*P tine pozitia ultimului termen al s.c. maximal, de la care mergem recurent inapoi penru a reconstitui sirul;
	Maxim tine lungimea celui mai lung s.c.*/
	
	fscanf(in, "%d", &n);
	for (i = 1; i <= n; i++){
		fscanf(in, "%d", &sir[i]);
		prec[i] = i;
	}
	
	for (i = 1; i <= n; i++){
		j = CautaMax(Maxim, sir[i]);
		if (j == Maxim || sir[i] < sir[M[j+1]]){
			if (j == Maxim) {Maxim++; P = i;}
			M[j+1] = i;
			prec[i] = M[j];
		}
	}
	
	fprintf(out, "%d\n", Maxim);
	Afiseaza(P);
	return 0;
}