Cod sursa(job #2265363)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 20 octombrie 2018 23:45:58
Problema Subsir 2 Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("subsir2.in");
ofstream out("subsir2.out");

const int NMAX = 5005;
const int VALMAX = 1000001;

int v[NMAX], dp[NMAX], aint[8 * VALMAX], minpref[NMAX];

void update(int pos, int val, int node, int le, int ri) {
    if(le == ri)
        aint[node] = max(aint[node], val);
    else {
        int mid = (le + ri) / 2;
        if(pos <= mid)
            update(pos, val, node * 2, le, mid);
        else
            update(pos, val, node * 2 + 1, mid + 1, ri);
        aint[node] = max(aint[node * 2], aint[node * 2 + 1]);
    }
}

int query(int from, int to, int node, int le, int ri) {
    if(from <= le && ri <= to)
        return aint[node];
    int mid = (le + ri) / 2;
    int ans = 0;
    if(from <= mid)
        ans = query(from, to, node * 2, le, mid);
    if(mid < to)
        ans = max(ans, query(from, to, node * 2 + 1, mid + 1, ri));
    return ans;
}

struct Data {
    int x, y;
    bool operator< (Data other) const {
        if(x == other.x)
            return y < other.y;
        return x < other.x;
    }
};

int main() {
    int n;
    in >> n;
    minpref[0] = VALMAX;
    for(int i = 1; i <= n; i ++) {
        in >> v[i];
        minpref[i] = min(v[i], minpref[i - 1]);
    }

    int scmax = NMAX;
    for(int i = n; i >= 1; i --) {
        dp[i] = 1 + query(v[i] + VALMAX, 2 * VALMAX, 1, 1, 2 * VALMAX);
        update(v[i] + VALMAX, dp[i], 1, 1, 2 * VALMAX);
        if(scmax > dp[i] && minpref[i - 1] > v[i])
            scmax = dp[i];
       // cout << i << " " << dp[i] << endl;
    }
    out << scmax << "\n";

        vector<Data> reconst[NMAX + 1];

    for(int i = 1; i <= n; i ++)

        reconst[dp[i]].push_back({v[i], i});

    for(int i = 1; i <= scmax; i ++)

        sort(reconst[i].begin(), reconst[i].end());

    int last = 0;

    for(int step = scmax; step >= 1; step --) {

        int i = 0;

        for(i = 0; i < reconst[step].size() && reconst[step][i].y < last; i ++);

        last = reconst[step][i].y;

        out << last << " ";

    }
    return 0;
}