Cod sursa(job #2570918)

Utilizator lucametehauDart Monkey lucametehau Data 4 martie 2020 19:59:33
Problema Subsir crescator maximal Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <algorithm>
#include <random>

using namespace std;

ifstream cin ("scmax.in");
ofstream cout ("scmax.out");

int n;

pair <int, int> v[100005], w[100005];
vector <int> ans;
int aint[400005];
/*random_device rd;
mt19937 rng(rd());
uniform_int_distribution <> gen(1, 2000000000);

void genTest() {
  n = gen(rng) % 5000 + 1;
  for(int i = 1; i <= n; i++)
    w[i].first = gen(rng), w[i].second = i;
}

int brut(int n, pair <int, int> w[]) {
  int dp[5005], ans = 0;
  for(int i = 1; i <= n; i++) {
    dp[i] = 1;
    for(int j = 1; j < i; j++) {
      if(w[j].first < w[i].first)
        dp[i] = max(dp[i], dp[j] + 1);
    }
    ans = max(ans, dp[i]);
  }
  return ans;
}*/

void update(int nod, int st, int dr, int ind, int val) {
  if(ind < st || dr < ind || st > dr)
    return;
  if(st == dr) {
    aint[nod] = val;
    return;
  }
  int mid = (st + dr) >> 1;
  update(2 * nod, st, mid, ind, val);
  update(2 * nod + 1, mid + 1, dr, ind, val);
  aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}

int query(int nod, int st, int dr, int l, int r) {
  if(st > dr || r < st || dr < l || l > r)
    return 0;
  if(l <= st && dr <= r)
    return aint[nod];
  int mid = (st + dr) >> 1;
  return max(query(2 * nod, st, mid, l, r), query(2 * nod + 1, mid + 1, dr, l, r));
}


void solve(int n, pair <int, int> v[]) {
  sort(v + 1, v + n + 1);
  for(int i = 1; i <= 4 * n; i++)
    aint[i] = 0;
  for(int i = 1; i <= n; i++) {
    int j = i;
    while(v[j].first == v[i].first && j <= n)
      j++;
    j--;
    int k = j;
    while(j >= i)
      update(1, 1, n, v[j].second, query(1, 1, n, 1, v[j].second - 1) + 1), j--;
    i = k;
  }
  int p = query(1, 1, n, 1, n), q, j = n;
  cout << p << "\n";
  while(query(1, 1, n, v[j].second, v[j].second) != p)
    j--;
  ans.push_back(v[j].first);
  for(int i = j - 1; i >= 1; i--) {
    q = query(1, 1, n, v[i].second, v[i].second);
    if(q + 1 == p)
      ans.push_back(v[i].first), p = q;
  }
  reverse(ans.begin(), ans.end());
  for(auto &i : ans)
    cout << i << " ";
}

int main() {
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> v[i].first, v[i].second = i;
  solve(n, v);
  return 0;
}