Cod sursa(job #3264959)

Utilizator divadddDavid Curca divaddd Data 26 decembrie 2024 00:08:33
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
using namespace std;
const int NMAX = 1e5+2;
using pii = pair<int, int>;
int n,a[NMAX],nrm[NMAX];
pii dp[NMAX];

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

struct MaxNode {
  pii val = {0, 0};
  MaxNode(){}
  MaxNode(pii _val): val(_val) {}
  MaxNode operator + (const MaxNode &oth) const {
    MaxNode ans;
    ans.val = max(val, oth.val);
    return ans;
  }
};

template<typename Node>
struct AIB {
  int n;
  vector<Node> bit;
  AIB(){}
  AIB(int _n){
    n = _n;
    bit.resize(n+1);
  }
  void update(int pos, Node val){
    for(int i = pos; i <= n; i += (i&-i)){
      bit[i] = bit[i] + val;
    }
  }
  Node query(int pos){
    Node ans;
    for(int i = pos; i > 0; i -= (i&-i)){
      ans = ans + bit[i];
    }
    return ans;
  }
};

int main() {
  fin >> n;
  vector<int> v;
  for(int i = 1; i <= n; i++){
    fin >> a[i];
    v.push_back(a[i]);
    dp[i] = {1, 0};
  }
  sort(all(v));
  v.erase(unique(all(v)), v.end());
  for(int i = 1; i <= n; i++){
    nrm[i] = 1 + lower_bound(all(v), a[i]) - v.begin();
  }

  int best = 0, pos = 0;
  AIB<MaxNode> aib(n);
  for(int i = 1; i <= n; i++){
    auto [plen, pt] = aib.query(nrm[i]-1).val;
    dp[i] = max(dp[i], {plen+1, pt});
    if(plen+1 > best){
      best = plen+1;
      pos = i;
    }
    aib.update(nrm[i], MaxNode({dp[i].first, i}));
  }

  fout << best << "\n";
  vector<int> ans;
  while(pos != 0){
    ans.push_back(a[pos]);
    pos = dp[pos].second;
  }
  reverse(all(ans));
  for(int it: ans){
    fout << it << " ";
  }
  return 0;
}