Cod sursa(job #2173942)

Utilizator TimoteiCopaciu Timotei Timotei Data 16 martie 2018 09:47:31
Problema Subsir crescator maximal Scor 55
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

#define For(i, x, y) for(int i = x; i <= y; ++i)
#define Forr(i, x, y) for(int i = x; i >= y; --i)
#define nMax 100005

using namespace std;

typedef struct {
   int val, poz;
} number;
typedef struct{
 int l, p;
} tree;
tree a, arb[(1 << 18)];
number x;
vector <number> v;
int n, ord[nMax], bestL[nMax], idx, lMax, last[nMax];
vector <int> sol;

bool comp(number x, number y){
 return (x.val < y.val);
}
void normalize(){
  sort(v.begin(), v.end(), comp);
  ord[v[0].poz] = 1;
  For(i, 1, v.size() - 1)
  if(v[i].val == v[i - 1].val) v.erase(v.begin() + i), i--;
  For(i, 1, v.size() - 1)
    ord[v[i].poz] = i + 1;
}
void update(int nod, int st, int dr, int a, int b)
{
    if(st == dr){
        arb[nod].l = b;
        arb[nod].p = a;
    }
    else {
        int mij = (st + dr) / 2;
        if(a <= mij) update(2 * nod, st, mij, a, b);
          else update(2 * nod + 1, mij + 1, dr, a, b);
        if(arb[2 * nod].l > arb[2 * nod + 1].l)
            arb[nod] = arb[2 * nod];
        else arb[nod] = arb[2 * nod + 1];
    }
}
void query(int nod, int st, int dr, int a, int b){
  if(st >= a and dr <= b){
    if(arb[nod].l > lMax) lMax = arb[nod].l, idx = arb[nod].p;
  }
  else {
    int mij = (st + dr) / 2;
    if(a <= mij) query(2 * nod, st, mij, a, b);
    if(b > mij) query(2 * nod + 1, mij + 1, dr, a, b);
  }
}
int main()
{
    ifstream fin("scmax.in");
    ofstream fout("scmax.out");
    fin >> n;
    For(i, 1, n){
      fin >> x.val;
      x.poz = i;
      v.push_back(x);
    }
    normalize();
    For(i, 1, n){
      lMax = 0;
      if(ord[i] != 0)
        query(1, 1, v.size(), 1, ord[i]);
      lMax++;
      update(1, 1, v.size(), ord[i], lMax);
      last[ord[i]] = idx;
    }
    fout << arb[1].l << '\n';
    int next = arb[1].p;
    while(next != 0){
        sol.push_back(v[next - 1].val);
        next = last[next];
    }
    Forr(i, sol.size() - 1, 0)
      fout << sol[i] << ' ';
    return 0;
}