Pagini recente » Cod sursa (job #1558837) | Cod sursa (job #163995) | Cod sursa (job #32202) | Cod sursa (job #1390661) | Cod sursa (job #2124974)
#include <bits/stdc++.h>
using namespace std;
/**
SURSA ASTA E CU INDICI CA SA VAD DACA INTRA, *WINK*... Nu ma judeca, pls!
dp[i] = capatul minim al unui subsir de lungime i
poz[i] = pozitia unde s-a inserat a[i] in vectorul dp
*/
const int Nmax = 1E5 + 5;
int a[Nmax];
int dp[Nmax];
int poz[Nmax];
int n, k;
int sol[Nmax];
void Read()
{
ifstream fin("scmax.in");
fin >> n;
for (int i = 1; i <= n; i++)
fin >> a[i];
fin.close();
}
/// caut in dp[1..k] cea mai din stanga pozitie md cu x <= dp[md]
int Binary_Search(int x)
{
int st, dr, md;
int poz;
st = 1; dr = k;
poz = k;
while (st <= dr)
{
md = (st + dr) / 2;
if (x <= a[dp[md]])
{
poz = md;
dr = md - 1;
}
else st = md + 1;
}
return poz;
}
void LIS()
{
int i, x, p;
/// Initializari
dp[1] = 1;
poz[1] = 1;
k = 1;
for (i = 2; i <= n; i++)
{
x = a[i];
if (x > a[dp[k]]) /// Putem lungi subsirul LEJER
{
dp[++k] = i;
poz[i] = k;
}
/// OPTIONAL (ca)
else if (x <= a[dp[1]]) /// Daca este mai mic decat toate il bagam JAPK la inceput
{
dp[1] = i;
poz[i] = 1;
}
else /// Trebuie inserat undeva unde va actuliza un minim
{ /// (<--)
/// Scrie mai sus -> Cea mai din stanga pozitie cu x <= dp[pozitie] pe (1..k)
p = Binary_Search(x);
dp[p] = i; /// Actualizam minimul ala
poz[i] = p;
}
}
}
void Reconstructie()
{
ofstream fout("scmax.out");
fout << k << "\n";
int i, lg;
lg = k;
/// RECONSTITUIM
for (i = n; lg > 0 && i >= 1; i--)
if (poz[i] == lg)
sol[lg--] = a[i];
/// AFISAM
for (i = 1; i <= k; i++)
fout << sol[i] << " ";
fout << "\n";
fout.close();
}
int main()
{
Read();
LIS();
Reconstructie();
return 0;
}