Cod sursa(job #2799147)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 12 noiembrie 2021 15:29:20
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 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;
}