Cod sursa(job #1479178)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 30 august 2015 17:43:15
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <ctype.h>

#define MAX_N 100000
#define BUFFSIZE 4096

int v[MAX_N + 1];    // vectorul dat
int cop[MAX_N + 1];  // copie a vectorul dat, folosit in reconstituire
int next[MAX_N + 1]; // vector folosit in normalizare si in reconstituirea solutiei
int d[MAX_N + 1];    // d[i] = lungimea celui mai lung subsir crescator care se termina in v[i]
int fen[MAX_N + 1];  // aib care retine dmax pe [1, i]
// folosite pentru parsare
char buffer[BUFFSIZE];
int pos = BUFFSIZE;

inline char getChr(FILE *f) {
  if (pos == BUFFSIZE) {
    fread(buffer, 1, BUFFSIZE, f);
    pos = 0;
  }
  return buffer[pos++];
}

inline int readInt(FILE *f) {
  int q = 0;
  char c;

  do {
    c = getChr(f);
  } while (!isdigit(c));
  do {
    q = (q << 1) + (q << 3) + (c - '0');
    c = getChr(f);
  } while (isdigit(c));
  return q;
}

void normalize(int n) {
  int len = 1;

  for (int i = 1; i <= n; i++) {
    next[i] = v[i];
  }
  std::sort(next + 1, next + n + 1);
  for (int i = 2; i <= n; i++) {
    if (next[len] != next[i]) {
      next[++len] = next[i];
    }
  }
  for (int i = 1; i <= n; i++) {
    v[i] = std::lower_bound(next + 1, next + len + 1, v[i]) - next;
  }
}

inline int fenQuery(int pos) {
  int maxD = fen[pos];
  for (; pos > 0; pos -= (pos & -pos)) {
    if (d[fen[pos]] > d[maxD]) {
      maxD = fen[pos];
    }
  }
  return maxD;
}

inline void fenUpdate(int pos, int ind, int n) {
  for (; pos <= n; pos += (pos & -pos)) {
    if (d[fen[pos]] < d[ind]) {
      fen[pos] = ind;
    }
  }
}

void printSol(int p, FILE *f) {
  if (p > 0) {
    printSol(next[p], f);
    fprintf(f, "%d ", cop[p]);
  }
}

int main(void) {
  int n, ans;
  FILE *f = fopen("scmax.in", "r");

  n = readInt(f);
  for (int i = 1; i <= n; i++) {
    v[i] = readInt(f);
    cop[i] = v[i];
  }
  fclose(f);

  normalize(n);

  ans = 1;
  for (int i = 1; i <= n; i++) {
    next[i] = fenQuery(v[i] - 1);
    d[i] = d[next[i]] + 1;
    fenUpdate(v[i], i, n);
    if (d[i] > d[ans]) {
      ans = i;
    }
  }

  f = fopen("scmax.out", "w");
  fprintf(f, "%d\n", d[ans]);
  printSol(ans, f);
  fclose(f);
  return 0;
}