Cod sursa(job #1419725)

Utilizator andreiagAndrei Galusca andreiag Data 16 aprilie 2015 11:29:40
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;
typedef unsigned int ui;
typedef pair<int, int> pii;

ui d = 1;

int a[100555];  // sequence
int b[100555];  // best result up to i
int ret[100555]; // answer sequence
int A[400555];

// translate from number to order and back
int num[100555]; // gives number based on the order in the sorted sequence;
map<int, int> ord; // gives the order of the number in the sorted sequence;

inline int max (int x, int y) { return x > y ? x : y; }

int query(int start, int finish, int l, int r, int ind) {
  if (start <= l && r <= finish)
    return A[ind];
  int mid = (l+r)/2;
  
  int x = start <= mid ? query (start, finish, l, mid, 2*ind) : 0;
  int y = finish > mid ? query (start, finish, mid+1, r, 2*ind+1) : 0;
  return max (x, y);
}

void update (int pos, int val) {
  int x = d + pos;
  A[x] = val;
  while (x > 1) {
    x /= 2;
    A[x] = max(A[2*x], A[2*x+1]);
  }
}

int main()
{
  ifstream f ("scmax.in");
  ofstream g ("scmax.out");
  
  ui N = 0, n = 0;
  f >> N;
  vector<int> v (N, 0);
  for (ui i = 0; i < N; i++) {
    f >> v[i];
    a[i] = v[i];
  }

  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  
  for (ui i = 0; i < v.size(); i++) {
    num[i] = v[i];
    ord[v[i]] = i;
  }
  
  for (ui i = 0; i < N; i++) {
    a[i] = ord[a[i]];
  }

  n = v.size();
  while (d < n) {
    d *= 2;
  }

  int ans = 0;
  for (ui i = 0; i < N; i++) {
    int x = a[i];
    int best = x > 0 ? query(0, x-1, 0, d-1, 1) + 1 : 1;
    b[i] = best;
    update(x, best);
    ans = max(ans, best);
  }
  
  int x = ans;
  for (int i = N-1; i >= 0; i--) {
    if (b[i] == x) {
      ret[--x] = num[a[i]];
    }
  }
  g << ans << '\n';
  for (int i = 0; i < ans; i++)
    g << ret[i] << ' ';
  g << '\n';

  return 0;
}