Cod sursa(job #2419353)

Utilizator pickleVictor Andrei pickle Data 8 mai 2019 09:18:49
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <stdio.h>
#include <bits/stdc++.h>

#define rep(i, n) for(int i = 0; i < n; i++)
#define repa(i, l, r) for (int i = l; i < r; i++)
#define repd(i, r, l) for (int i = r; i > l; i--)

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
ifstream fin ("scmax.in");
ofstream fout ("scmax.out");
const int Nmax = 100555;
int orig[Nmax]; // original numbers
int a[Nmax]; // Normalized Numbers: 0 <= a[i] <= count distinct(orig[i])
int v[Nmax]; // sorted, unique
int par[Nmax];

pii Arb[3*Nmax];
void update(int nod, int l, int r, int pos, pii val);
pii query(int nod, int l, int r, int a, int b);

int main(void) {
  int N;
  fin >> N;
  rep(i, N) {
    fin >> orig[i];
    a[i] = v[i] = orig[i];
  }

  sort(v, v+N);
  int pos = unique(v, v+N) - v;
  rep(i, N) {
    // position of orig[i] in the new order.
    a[i] = lower_bound(v, v+pos, orig[i]) - v;
  }

  for(int i = 0; i < N; i++) {
    int best = 0, pos = -1;
    if (a[i] > 0) {
      pii previous = query(1, 0, N-1, 0, a[i] - 1);
      best = previous.first;
      pos  = previous.second;
    }
    if (best == 0) { pos = -1; }
    par[i] = pos;
    update(1, 0, N-1, a[i], {best + 1, i});
  }

  pii result = query(1, 0, N-1, 0, pos);
  fout << result.first << endl;
  vi subsequence;
  for(int pos = result.second; pos != -1; pos = par[pos]) {
    subsequence.push_back(orig[pos]);
  }
  reverse(subsequence.begin(), subsequence.end());
  for(auto el: subsequence) {
    fout << el << ' ';
  }
  fout << endl;
  return 0;
}

void update(int nod, int l, int r, int pos, pii val) {
  if (l == r) {
    Arb[nod] = val;
    return;
  }
  int mid = l + (r - l)/2;
  if (pos <= mid) {
    update(2*nod, l, mid, pos, val);
  } else {
    update(2*nod+1, mid+1, r, pos, val);
  }
  Arb[nod] = max(Arb[2*nod], Arb[2*nod+1]);
}

pii query(int nod, int l, int r, int a, int b) {
  if (a <= l && r <= b) {
    return Arb[nod];
  }
  int mid = l + (r - l)/2;

  if (b < mid+1) {
    return query(2*nod, l, mid, a, b);
  } else if (a > mid) {
    return query(2*nod+1, mid+1, r, a, b);
  } else {
    return max(
            query(2*nod, l, mid, a, b),
            query(2*nod+1, mid+1, r, a, b)
           );
  }
}