Cod sursa(job #2032985)

Utilizator preda.andreiPreda Andrei preda.andrei Data 5 octombrie 2017 22:32:53
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <algorithm>
#include <fstream>
#include <vector>

using namespace std;

struct ListTop
{
  int len, index;

  bool operator<(const ListTop &other) const
  {
    return len < other.len;
  }

  void TryUpdate(int new_len, int new_ind)
  {
    if (new_len > len) {
      len = new_len;
      index = new_ind;
    }
  }
};

using Bit = vector<ListTop>;

vector<int> Normalise(const vector<int> &vec)
{
  vector<int> sorted(vec);
  sort(sorted.begin(), sorted.end());

  vector<int> norm{sorted[0]};
  for (size_t i = 1; i < sorted.size(); ++i) {
    if (sorted[i] != norm.back()) {
      norm.push_back(sorted[i]);
    }
  }
  return norm;
}

int FindOrder(const vector<int> &vec, int val)
{
  int pos = -1;
  int power = (1 << 25);

  while (power > 0) {
    if (pos + power < (int)vec.size() && vec[pos + power] < val) {
      pos += power;
    }
    power >>= 1;
  }
  return pos + 1;
}

inline int Lsb(int x) { return x & -x; }

ListTop FindBest(const Bit &bit, int pos)
{
  ListTop best{0, -1};
  while (pos > 0) {
    best = max(best, bit[pos]);
    pos -= Lsb(pos);
  }
  return best;
}

void Update(Bit &bit, int pos, int len, int ind)
{
  while (pos < (int)bit.size()) {
    bit[pos].TryUpdate(len, ind);
    pos += Lsb(pos);
  }
}

void Print(const vector<int> &vec, const vector<int> &pred, int ind, ofstream &fout)
{
  if (pred[ind] != -1) {
    Print(vec, pred, pred[ind], fout);
  }
  fout << vec[ind] << " ";
}

int main()
{
  ifstream fin("scmax.in");
  ofstream fout("scmax.out");

  int n;
  fin >> n;

  vector<int> vec(n);
  for (auto &elem : vec) {
    fin >> elem;
  }

  auto norm = Normalise(vec);
  Bit bit(norm.size() + 1, {0, -1});

  int max_len = 0;
  int max_end = -1;
  vector<int> pred(n, -1);

  for (int i = 0; i < n; ++i) {
    auto order = FindOrder(norm, vec[i]) + 1;
    auto top = FindBest(bit, order - 1);
    auto len = top.len + 1;

    if (len > max_len) {
      max_len = len;
      max_end = i;
    }

    pred[i] = top.index;
    Update(bit, order, len, i);
  }

  fout << max_len << "\n";
  Print(vec, pred, max_end, fout);

  return 0;
}