Cod sursa(job #1608390)

Utilizator dm1sevenDan Marius dm1seven Data 22 februarie 2016 01:03:39
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.31 kb
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <utility>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include <stack>
#include <fstream>
#include <chrono>
using namespace std;
using namespace std::chrono;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<ull> vull;
typedef vector<vull> vvull;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
typedef vector<string> vstring;

#define fs first
#define sc second
#define pb push_back
// forward strict for, most common
#define fors(i, a, n) for (int i = (int) (a); i < (int) (n); ++i)
// forward inclusive for
#define fori(i, a, n) for (int i = (int) (a); i <= (int) (n); ++i)
// backward for, inclusive
#define forb(i, n, a) for (int i = (int) (n); i >= (a); --i)

int main() {    
    
    ifstream in("scmax.in");
    ofstream out("scmax.out");
    int n;
    in >> n;
    vint a(n + 1);
    fori(i, 1, n) in >> a[i];
    // vector
    // given i and elements a1, a2, ... ai. We analyse the sub-sequences of length j up to i.
    // for a sub-sequence of length j, we keep the smallest possible value a of the tail (or its id).
    // see the following links for further explanations: 
    // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
    // http://www.algorithmist.com/index.php/Longest_Increasing_Subsequence
    vint si(n + 1), p(n + 1);
    si[1] = 1;
    p[1] = 0;
    int L = 1;

    fori(i, 2, n) {
        // find j by binary search      
        // a[si[u-1]] < a[i] <= a[si[u]];
        int u = 1, v = L;
        while (u <= v) {
            int m = (u + v + 1) / 2;
            if (a[si[m]] < a[i]) u = m + 1;
            else v = m - 1;
        }
        // we found the lower-bound u
        if (u > L) L = u; // enlarge
        si[u] = i;
        p[i] = si[u - 1];
    }
    
    // reconstruct
    vint lis(L + 1);
    int k = si[L];
    forb(i, L, 1) {
        lis[i] = a[k];
        k = p[k];
    }
    
    out << L << endl;
    fori(i, 1, L) out << lis[i] << " ";
    
    return 0;
}