Cod sursa(job #1706505)

Utilizator BrandonChris Luntraru Brandon Data 22 mai 2016 18:09:50
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.29 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

class InputReader {
public:
  InputReader() {}
  InputReader(const char *file_name) {
    input_file = fopen(file_name, "r");
    cursor = 0;
    fread(buffer, SIZE, 1, input_file);
  }
  inline InputReader &operator >>(int &n) {
    while (buffer[cursor] < '0' || buffer[cursor] > '9') {
      advance();
    }
    n = 0;
    while ('0' <= buffer[cursor] && buffer[cursor] <= '9') {
      n = n * 10 + buffer[cursor] - '0';
      advance();
    }
    return *this;
  }
private:
  FILE *input_file;
  static const int SIZE = 1 << 17;
  int cursor;
  char buffer[SIZE];
  inline void advance() {
    ++ cursor;
    if (cursor == SIZE) {
      cursor = 0;
      fread(buffer, SIZE, 1, input_file);
    }
  }
};

InputReader cin("scmax.in");
ofstream cout("scmax.out");

const int MaxN = 100005;

vector <int> srt = {-1}, AnsList;
int pos[MaxN], v[MaxN], father[MaxN], best[MaxN], BITree[MaxN];
int n, Ans;

inline void Update(int pos, int val) {
  for (; pos <= n; pos += pos & (-pos)) {
    if (best[val] > best[BITree[pos]]) BITree[pos] = val;
  }
}

inline int Query(int pos) {
  int ans = 0;
  for (; pos; pos -= pos & (-pos)) {
    if (best[BITree[pos]] > best[ans]) ans = BITree[pos];
  }
  return ans;
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> v[i];
    srt.push_back(v[i]);
  }

  sort(srt.begin(), srt.end());
  srt.erase(unique(srt.begin(), srt.end()), srt.end());
  int curr = 1;

  for (int i = 1; i <= n; ++i) {
    pos[i] = lower_bound(srt.begin() + 1, srt.end(), v[i]) - srt.begin();
  }

  for (int i = 1; i <= n; ++i) {
    father[i] = Query(pos[i] - 1);
    best[i] = best[father[i]] + 1;
    Update(pos[i], i);
  }

  for (int i = 1; i <= n; ++i) {
    if (best[i] > best[Ans]) Ans = i;
  }
  cout << best[Ans] << '\n';

  for (int i = Ans; i; i = father[i]) {
    AnsList.push_back(v[i]);
  }

  for (int i = AnsList.size() - 1; i >= 0; --i) cout << AnsList[i] << ' ';
  cout << '\n';
  return 0;
}

/*#include <fstream>
#include <vector>

using namespace std;

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

vector <int> ans;

int n, v[100005], previous[100005], pos[100005], pos_size = 1;

inline int bin_search(int l, int r, int val) {
    int med, ans = 0;

    while(l <= r) {
        med = (l + r) / 2;

        if(v[pos[med]] < val) {
            l = med + 1;
            ans = med;
        }
        else {
            r = med - 1;
        }
    }

    return ans;
}

int main() {
    cin >> n;

    for(int i = 1; i <= n; ++i) {
        cin >> v[i];
    }

    pos[1] = 1;

    for(int i = 2; i <= n; ++i) {
        if(v[i] > v[pos[pos_size]]) {
            ++pos_size;
            pos[pos_size] = i;
            previous[i] = pos[pos_size - 1];
        }
        else {
            int new_pos = bin_search(0, pos_size, v[i]);
            pos[new_pos + 1] = i;
            previous[i] = pos[new_pos];
        }
    }

    cout << pos_size << '\n';

    for(int i = pos[pos_size]; i >= 1; i = previous[i]) {
       ans.push_back(v[i]);
    }

    for(int i = ans.size() - 1; i >= 0; --i) {
        cout << ans[i] << ' ';
    }

    cout << '\n';
    return 0;
}*/