Cod sursa(job #2830968)

Utilizator Avram_RobertAvram Robert Ionut Avram_Robert Data 10 ianuarie 2022 16:21:38
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;
}