Cod sursa(job #3165023)

Utilizator mariusn01Marius Nicoli mariusn01 Data 5 noiembrie 2023 09:52:37
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.36 kb
#include <stdio.h>
#include <algorithm>
#define DIM 100001

using namespace std;

int V[DIM], W[DIM], A[DIM], i, p, N, Maxim, Max, K, P[DIM], T[DIM], pozMax, poz;

FILE *f = fopen("scmax.in","r");
FILE *g = fopen("scmax.out","w");

void drum(int p) {
	if (p) {
		drum(T[p]);
		fprintf(g,"%d ",W[p]);
	}
}

inline int lsb(int x) {
	return x & -x;
}

int cauta(int x) {
	int p = 1, u = K, m;
	while (p<=u) {
		m = (p+u) >> 1;
		if (W[m] == x)
			return m;
		if (W[m] < x)
			p = m+1;
		else
			u = m-1;
	}
}

int query (int p, int &pp) {
	int maxim = 0;
	pp = 0;
	for (;p;p-=lsb(p)) {
		if (maxim < A[p]) {
			maxim = A[p];
			pp = P[p];
		}
	}
	return maxim;
}

void update(int p, int v) {
	int aux = p;
	for (;p<=K;p+=lsb(p))
		if (A[p] < v) {
			A[p] = v;
			P[p] = aux;
		}
}


int main() {

	fscanf(f,"%d",&N);
	for (i=1;i<=N;i++) {
		fscanf(f,"%d",&V[i]);
		W[i] = V[i];
	}
	fclose(f);
	sort(W+1, W+N+1);
	K = 1;
	for (i=2;i<=N;i++)
		if (W[i] != W[K])
			W[++K] = W[i];

//	A[i] = maximul din L pentru valori ce corespund elementelor din V din intervalul [  V[i-2^k + ] V[i]   ]

	for (i=1;i<=N;i++) {
		p = cauta(V[i]);
		int Max = query(p-1, poz);
		if (1+Max > Maxim) {
			Maxim = 1 + Max;
			pozMax = p;
		}
		update(p, 1+Max);
		T[p] = poz;
	}

	fprintf(g,"%d\n",Maxim);
	drum(pozMax);
	return 0;
}