Cod sursa(job #2564666)

Utilizator theo2003Theodor Negrescu theo2003 Data 2 martie 2020 09:03:14
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.49 kb
#include <map>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream cin("scmax.in");
ofstream cout("scmax.out");
char f[3700000];
map<int, int> m;
int sq[110000], sq1[110000], pre[110000], rev[110000], n, maxv = -1, maxp, fi = 0;
void read(int &i){
    i = 0;
    while((f[fi] > '9') || (f[fi] < '0'))
        fi++;
    while((f[fi] >= '0') && (f[fi] <= '9')){
        i *= 10;
        i += f[fi] - '0';
        fi++;
    }
}
struct aint {
    aint *a, *b;
    int val, pre, l, r;
};
aint *mem = new aint[320000];
void build(aint *i, int l, int r) {
    i->l = l;
    i->r = r;
    i->val = -1;
    i->pre = -1;
    if(l != r) {
        i->a = mem++;
        i->b = mem++;
        build(i->a, l, (l + r)/2);
        build(i->b, (l + r)/2 + 1, r);
    }
}
pair<int, int> update(aint *i, int p, int v, int x) {
    if((i->l == p) && (i->r == p)) {
        if(v > i->val)
            return {i->val = v, i->pre = x};
        else
            return {i->val, i->pre};
    } else {
        pair<int, int> a = update((p > i->a->r) ? i->b : i->a, p, v, x);
        if(a.first > i->val) {
            return {i->val = a.first, i->pre = a.second};
        } else
            return {i->val, i->pre};
    }
}
pair<int, int> query(aint *i, int l, int r) {
    if((i->l == l) && (i->r == r))
        return {i->val, i->pre};
    else if(i->a->r >= r)
        return query(i->a, l, r);
    else if(i->a->r < l)
        return query(i->b, l, r);
    else {
        pair<int, int> a = query(i->a, l, i->a->r), b = query(i->b, i->b->l, r);
        if(a.first > b.first)
            return a;
        else
            return b;
    }
}
aint *root = new aint;
int main() {
    cin.read(f, 3700000);
    read(n);
    for(int x = 0; x<n; x++) {
        read(sq[x]);
        sq1[x] = sq[x];
    }
    sort(sq1, sq1 + n);
    for(int x = 0, y = 1; x<n; x++) {
        if(m.find(sq1[x]) == m.end())
            m[sq1[x]] = y++;
    }
    build(root, 0, m.size());
    update(root, 0, 0, -1);
    for(int x = 0; x<n; x++) {
        pair<int, int> best = query(root, 0, m[sq[x]] - 1);
        pre[x] = best.second;
        if((best.first + 1) > maxv){
            maxv = best.first + 1;
            maxp = x;
        }
        update(root, m[sq[x]], best.first + 1, x);
    }
    cout<<maxv<<'\n';
    int x = 0;
    while(maxp != -1){
        rev[x++] = sq[maxp];
        maxp = pre[maxp];
    }
    while(x--){
        cout<<rev[x]<<' ';
    }
    return 0;
}