Cod sursa(job #3234007)

Utilizator betybety bety bety Data 5 iunie 2024 20:04:57
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
const int lim = 1e5 + 4;
const int inf = 1e9 + 7;
using pii = pair<int, int>;
pii tree[4 * lim];
pii bef[lim];
int iv[lim];
int v[lim];
pii f[lim];
int n, cnt = 2;
void build(int nod, int l, int r) {
  if (l == r) {
    tree[nod] = make_pair(-inf, -1);
    return;
  }
  int med = (l + r) >> 1;
  build(2 * nod, l, med);
  build(2 * nod + 1, med + 1, r);
  tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]);
}
void update(int nod, int l, int r, int ind, int lung) {
  if (l == r) {
    tree[nod] = make_pair(lung, ind);
    return;
  }
  int med = (l + r) >> 1;
  if (v[ind] <= med) {
    update(2 * nod, l, med, ind, lung);
  } else {
    update(2 * nod + 1, med + 1, r, ind, lung);
  }
  tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]);
}
pii query(int nod, int l, int r, int a, int b) {
  if (a <= l and r <= b) {
    return tree[nod];
  }
  int med = (l + r) >> 1;
  pii lmax = make_pair(-inf, -inf);
  pii rmax = make_pair(-inf, -inf);
  if (a <= med) {
    lmax = query(2 * nod, l, med, a, b);
  }
  if (b > med) {
    rmax = query(2 * nod + 1, med + 1, r, a, b);
  }
  return max(lmax, rmax);
}
int main() {
  in >> n;
  for (int i = 1; i <= n; ++i) {
    in >> iv[i];
    f[i] = make_pair(iv[i], i);
  }
  sort(f + 1, f + n + 1);
  v[f[1].second] = cnt;
  for (int i = 2; i <= n; ++i) {
    cnt += (f[i].first != f[i - 1].first);
    v[f[i].second] = cnt;
  }
  int unde = -1;
  int maxim = 0;
  build(1, 1, cnt);
  for (int i = 1; i <= n; ++i) {
    pii req = query(1, 1, cnt, 1, v[i] - 1);
    if (req.first == -inf) {
      bef[i] = make_pair(-1, 1);
    } else {
      bef[i] = make_pair(req.second, req.first + 1);
    }
    update(1, 1, cnt, i, bef[i].second);
    if (bef[i].second > maxim) {
      unde = i;
      maxim = bef[i].second;
    }
  }
  out << maxim << '\n';
  stack<int> ans;
  for (; unde != -1; unde = bef[unde].first) {
    ans.push(unde);
  }
  while (!ans.empty()) {
    out << iv[ans.top()] << ' ';
    ans.pop();
  }
  out << '\n';
  return 0;
}