Cod sursa(job #946597)

Utilizator MariusGeantaMarius Geanta MariusGeanta Data 4 mai 2013 22:36:56
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
/* O(n * log n) solution to longest strictly increasing subsequence */
#include <iostream>
#include <string.h>
#include <stdio.h>

#define NMAX 100000
#define FILEIN "scmax.in"
#define FILEOUT "scmax.out"

using namespace std;

int A[NMAX];
int tail[NMAX + 1];
int prevInd[NMAX + 1];
int sol[NMAX];


// Binary search to find the ceil of key in array A (note boundaries in the caller)
int CeilIndex(int l, int r, int key) {
    int m;

	while ( r - l > 1 ) {
		m = l + (r - l) / 2;
		(A[tail[m]] >= key ? r : l) = m;
	}

    return r;
}

void constrSol(int len) {
	int i;

	for (i = tail[len - 1]; i >= 0; i = prevInd[i]) {
		sol[--len] = A[i];
	}
}
 
int LongestIncreasingSubsequenceLength(int A[], int size) {
    // Add boundary case, when array size is one
 
    int len; // always points empty slot
 
    tail[0] = 0;
	prevInd[0] = -1;
    len = 1;
    for ( int i = 1; i < size; i++ ) {
        if( A[i] < A[tail[0]] ) {
            // new smallest value
            tail[0] = i;
		}
        else if( A[i] > A[tail[len-1]] ) {
            // A[i] wants to extend largest subsequence
			prevInd[i] = tail[len - 1];
            tail[len++] = i;
		}
        else {
            // A[i] wants to be current end candidate of an existing subsequence
            // It will replace ceil value in tail
            int ceil = CeilIndex(-1, len - 1, A[i]);
			prevInd[i] = tail[ceil - 1];
            tail[ceil] = i;
		}
    }

	constrSol(len);
 
    return len;
}

void read_file(const char *filename, int &n )
{
	FILE *f = fopen(filename, "r");

	fscanf(f, "%d", &n);

	for ( int i = 0; i < n; i++ ) {
		fscanf(f, "%d", &A[i]);
	}

	fclose(f);
}

void print_res(const char *filename, const int &res)
{
	FILE *f = fopen(filename, "w");

 	fprintf(f, "%d\n", res);

	for (int i = 0; i < res; i++) {
		fprintf(f, "%d ", sol[i]);
	}
	fprintf(f, "\n");
 
	fclose(f);
}
 
int main()
{
	int n;
 
	read_file(FILEIN, n);

	int res = LongestIncreasingSubsequenceLength(A, n);
 	
	print_res(FILEOUT, res);
    
	return 0;
}