Cod sursa(job #2799144)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 12 noiembrie 2021 15:28:08
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <climits>

using namespace std;

const int NMAX = 100000;

int v[1 + NMAX];
int dp[1 + NMAX];
int lastIndex[1 + NMAX]; /// lastIndex[i] = pozitia pe care se afla ///valoarea tinuta in dp[i];
int tata[1 + NMAX]; /// Daca v[i] face parte dintr-un subsir ///crescator, atunci tata[i] tine de fapt un j care inseamna faptul ///ca v[j] era elementul anterior lui v[i] in subsirul crescator in ///care se afla v[i]. v[i] se poate afla in mai multe subsiruri ///crescatoare, dar in asta il tinem pe ala de lungime maxima si ///care se termina in valoare cat mai mica, adica ce tinem in dp de ///fapt.

int cautareBinara(int st, int dr, int val)
{
  int sol = 0;

  while (st <= dr)
  {
    int mij = (st + dr) / 2;

    if (dp[mij] < val)
    {
      sol = mij;
      st = mij + 1;
    }
    else
    {
      dr = mij - 1;
    }
  }

  return sol;
}

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

void afisareSolutie(int index)
{
  if (tata[index] != 0)
    afisareSolutie(tata[index]);

  out << v[index] << ' ';
}

int main()
{
  int n;
  in >> n;

  int sol = 0;

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

    dp[i] = INT_MAX;

    int poz = cautareBinara(0, i, v[i]);

    dp[poz + 1] = v[i];
    lastIndex[poz + 1] = i;
    tata[i] = lastIndex[poz];

    if (poz + 1 > sol)
      sol = poz + 1;
  }

  out << sol << '\n';

  afisareSolutie(lastIndex[sol]);

  out << '\n';

  return 0;
}