Cod sursa(job #1365404)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 28 februarie 2015 11:49:05
Problema Subsir crescator maximal Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <set>
#include <cassert>

using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

const int maxn = 100005;
const int mod = 666013;

int n, m, a[maxn], v[maxn], cnt;
set <int> s;
vector <pair<int, int> > _hash[mod];

inline void insert_hash(int pos, int value) {
    int key = pos % mod;
    _hash[key].push_back(make_pair(pos, value));
}

inline int gethash(int pos) {
    int key = pos % mod;
    for(vector <pair<int, int> > :: iterator it = _hash[key].begin() ; it != _hash[key].end() ; ++ it)
        if(it->first == pos)
            return it->second;
    assert(false);
}

int aib[maxn], father[maxn], dp[maxn];

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

inline void update(int pos, int value) {
    for(int i = pos ; i <= cnt ; i += lsb(i))
        if(dp[aib[i]] < dp[value])
            aib[i] = value;
}

inline int query(int pos) {
    int ret = aib[pos];
    for(int i = pos ; i > 0 ; i -= lsb(i))
        if(dp[aib[i]] > dp[ret])
            ret = aib[i];
    return ret;
}

inline void write(int node) {
    if(father[node])
        write(father[node]);
    fout << a[node] << ' ';
}

int main() {
    fin >> n;
    for(int i = 1 ; i <= n ; ++ i) {
        fin >> a[i];
        s.insert(a[i]);
    }
    for(set<int> :: iterator it = s.begin() ; it != s.end() ; ++ it)
        insert_hash(*it, ++ cnt);
    int maxi = 1, posmax = 1;
    for(int i = 1 ; i <= n ; ++ i) {
        int aux = gethash(a[i]);
        int pos = query(aux - 1);
        dp[i] = dp[pos] + 1;
        update(aux, i);
        if(maxi < dp[i]) {
            maxi = dp[i];
            posmax = i;
        }
    }
    fout << maxi << '\n';
    write(posmax);
}