Cod sursa(job #3226648)

Utilizator TeodorLuchianovTeo Luchianov TeodorLuchianov Data 22 aprilie 2024 13:47:03
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;

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

int const NMAX = 1e5;
int arr[1 + NMAX];
int ind[1 + NMAX];

void buildPos(int n) {
  vector <int> aux;
  for(int i = 1;i <= n;i++) {
    aux.push_back(arr[i]);
  }
  sort(aux.begin(), aux.end());
  aux.erase(unique(aux.begin(), aux.end()), aux.end());
  map <int, int> valPos;
  for(int i = 0;i < aux.size();i++) {
    valPos[aux[i]] = i+1;
  }
  for(int i = 1;i <= n;i++) {
    ind[i] = valPos[arr[i]];
  }
}

pair <int, int> aib[1 + NMAX];
int previ[1 + NMAX];

void update(int pos, int leng, int last) {
  for(int i = pos;i <= NMAX;i = 2 * i - (i & (i-1))) {
    aib[i] = max(aib[i], {leng, last});
  }
}

pair <int, int> query(int pos) {
  pair <int, int> ans = {0, 0};
  for(int i = pos;i > 0;i = (i & (i-1))) {
    ans = max(ans, aib[i]);
  }
  return ans;
}

int main() {

  int n;
  in >> n;
  for(int i = 1;i <= n;i++) {
    in >> arr[i];
  }
  buildPos(n);
  int ans = 0, last = 0;
  for(int i = 1;i <= n;i++) {
    pair <int, int> temp = query(ind[i]-1);
    temp.first++;
    previ[i] = temp.second;
    update(ind[i], temp.first, i);
    if(ans < temp.first) {
      ans = temp.first;
      last = i;
    }
  }
  vector <int> sol;
  while(last != 0) {
    sol.push_back(last);
    last = previ[last];
  }
  out << ans << '\n';
  for(int i = sol.size()-1;i >= 0;i--) {
    out << arr[sol[i]] << ' ';
  }
  return 0;
}