Cod sursa(job #1805285)

Utilizator tudorcomanTudor Coman tudorcoman Data 13 noiembrie 2016 17:03:48
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb

#include <cstdio>
#include <algorithm>
#include <stack>
#include <functional>
using namespace std;

const int maxN = 100020;
typedef pair<int, int> pii;

int arb[maxN << 1];
pii v[maxN];

void update(int nod, int val, int pos, int st, int dr) {
  if(st == dr)
    arb[nod] = val;
  else {
    int mid = (st + dr) >> 1, k = nod << 1;
    if(pos <= mid)
      update(k, val, pos, st, mid);
    else
      update(k + 1, val, pos, mid + 1, dr);
    arb[nod] = max(arb[k], arb[k + 1]);
  }
}

int query(int nod, int x, int y, int st, int dr) {
  if(x <= st and dr <= y)
    return arb[nod];
  else {
    int mid = (st + dr) >> 1, k = nod << 1;
    int ans = 0;
    if(x <= mid)
      ans = max(ans, query(k, x, y, st, mid));
    if(y > mid)
      ans = max(ans, query(k + 1, x, y, mid + 1, dr));
    return ans;
  }
}

int dp[maxN], x[maxN];

int main() {
  freopen("scmax.in", "r", stdin);
  freopen("scmax.out", "w", stdout);
  int N;
  scanf("%d", &N);
  for(int i = 1; i <= N; ++ i) {
    scanf("%d", &v[i].first);
    v[i].second = i;
    x[i] = v[i].first;
  }

  sort(v + 1, v + N + 1, [] (const pii& a, const pii& b) {
    if(a.first == b.first)
      return a.second > b.second;
    return a.first < b.first;
  });

  int p;
  for(p = 1; p < N; p <<= 1);

  for(int i = 1; i <= N; ++ i) {
    int k = (v[i].second == 1) ? 0 : query(1, 1, v[i].second - 1, 1, p);
    update(1, k + 1, v[i].second, 1, p);
    dp[v[i].second] = k + 1;
  }

  int sol = query(1, 1, N, 1, p);
  printf("%d\n", sol);

  stack<int> st;
  for(int i = N; i; -- i) {
    if(dp[i] == sol) {
      st.push(x[i]);
      -- sol;
    }
  }

  while(!st.empty()) {
    printf("%d ", st.top());
    st.pop();
  }
  return 0;
}