Cod sursa(job #1560331)

Utilizator geni950814Geni Geni geni950814 Data 2 ianuarie 2016 16:08:59
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include <fstream>
#include <algorithm>
#include <limits>
#include <stack>
#include <iostream>

using namespace std;

const int MAX = 100000;
const int INF = numeric_limits<int>::max();
const int NEG_INF = numeric_limits<int>::min();

int V[MAX], dp[MAX], N, minVal[MAX], past[MAX];

bool inRange(int n) {
    return n >=0 && n < N;
}

void getResult(stack<int>& result, const int& maxLength) {
    int index = minVal[maxLength];
    while(index != -1) {
        result.push(V[index]);
        index = past[index];
    }
}

int binSearch(const int& n) {
    int start = 0;
    int end = N;
    int result;
    while(start < end) {
        int mid = (start+end)/2;
        int mv = minVal[mid];
        if(inRange(mv)) {
            mv = V[mv];
        }
        if(mv < n) {
            result = mid;
            start = mid + 1;
        } else {
            end = mid;
        }
    }

    if(start < N && inRange(minVal[start]) && V[minVal[start]] < n) {
        result = start;
    }
    
    return result;
}

int main() {
    
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);

    scanf("%d", &N);

    fill(minVal+1, minVal+MAX, INF);
    fill(past, past+MAX, -1);

    minVal[0] = NEG_INF;
    
    int maxLength = 0; 

    for(int i = 0; i < N; i++) {
        scanf("%d", &V[i]);
        //cout << "i: " << i << endl;

        int prev = binSearch(V[i]);
        //cout << "prev: " << prev << endl;

        dp[i] = 1 + prev;
        maxLength = max(maxLength, dp[i]);

        //cout << "dp[" << i << "]: " << dp[i] << endl;

        int mv = minVal[dp[i]];
        if(inRange(mv)) {
            mv = V[mv];
        }

        if(mv > V[i]) {
            minVal[dp[i]] = i;
        }
        //cout << "minVal[" << dp[i] << "]: " << minVal[dp[i]] << endl;
        
        if(prev != 0) {
            past[i] = minVal[prev];
        }
        //cout << "past[" << i << "]: " << past[i] << endl;
    }

    printf("%d", maxLength);
    cout << endl;
    stack<int> result;
    getResult(result, maxLength);
    while(result.size() > 0) {
        printf("%d ", result.top());
        result.pop();
    }  
    


    /*
    int prev;

    for(int i = 0; i < N; i++){
        for(int j = 0; j < i; j++) {
            prev = 0;
            if(dp[j] < dp[i] && prev < dp[j]) {
                prev = dp[j];
            }
        }
        dp[i] = prev+1;
    }

    */

    return 0;
}