Cod sursa(job #2250297)

Utilizator vladm98Munteanu Vlad vladm98 Data 30 septembrie 2018 13:37:47
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.05 kb
#include <bits/stdc++.h>

using namespace std;

class Reader {
public:
    Reader(const string& filename):
            m_stream(filename),
            m_pos(kBufferSize - 1),
            m_buffer(new char[kBufferSize]) {
        next();
    }

    Reader& operator>>(int& value) {
        value = 0;
        while (current() < '0' || current() > '9')
            next();
        while (current() >= '0' && current() <= '9') {
            value = value * 10 + current() - '0';
            next();
        }
        return *this;
    }

private:
    const int kBufferSize = 32768;

    char current() {
        return m_buffer[m_pos];
    }

    void next() {
        if (!(++m_pos != kBufferSize)) {
            m_stream.read(m_buffer.get(), kBufferSize);
            m_pos = 0;
        }
    }

    ifstream m_stream;
    int m_pos;
    unique_ptr<char[]> m_buffer;
};

int maximum [100005];
int before [100005];
int v[100005];
int dp[100005];
int reversed[100005];
pair <int, int> normalization[100005];

int mostUnsiginficantBit (int x) {
    return x & (-x);
}

void updateValue (int n, int position, int value) {
    while (position <= n) {
        if (dp[maximum[position]] < dp[value]) {
            maximum[position] = value;
        }
        position += mostUnsiginficantBit(position);
    }
}

int getMaximum (int position) {
    int current = 0;
    assert(position >= 0);
    while (position) {
        if (dp[current] < dp[maximum[position]]) {
            current = maximum[position];
        }
        position -= mostUnsiginficantBit(position);
    }
    return current;
}

int main() {
//    ifstream fin ("input");
//    ofstream fout ("output");
    Reader fin ("scmax.in");
    ofstream fout ("scmax.out");
    int n;
    fin >> n;
    for (int i = 1; i <= n; ++i) {
        fin >> v[i];
        normalization[i - 1] = make_pair(v[i], i);
    }
    sort (normalization, normalization + n);
    int currentValue = 1;
    for (int i = 0; i < n; ++i) {
        if (i + 1 < n and normalization[i].first < normalization[i + 1].first) {
            reversed[currentValue] = normalization[i].first;
            normalization[i].first = currentValue;
            currentValue += 1;
        }
        else {
            reversed[currentValue] = normalization[i].first;
            normalization[i].first = currentValue;
        }
        swap (normalization[i].first, normalization[i].second);
    }
    sort (normalization, normalization + n);
    for (int i = 1; i <= n; ++i) {
        v[i] = normalization[i - 1].second;
    }
    int theBest = 0;
    for (int i = 1; i <= n; ++i) {
        int bestPosition = getMaximum(v[i] - 1);
        dp[i] = dp[bestPosition] + 1;
        before[i] = bestPosition;
        if (dp[theBest] < dp[i]) {
            theBest = i;
        }
        updateValue(currentValue, v[i], i);
    }
    fout << dp[theBest] << '\n';
    vector <int> answer;
    while (theBest) {
        answer.push_back(reversed[v[theBest]]);
        theBest = before[theBest];
    }
    reverse (answer.begin(), answer.end());
    for (auto x : answer) {
        fout << x << ' ';
    }
    return 0;
}