Pagini recente » Cod sursa (job #3318806) | Cod sursa (job #1182086) | Monitorul de evaluare | Cod sursa (job #1016042) | Cod sursa (job #3317739)
#include <fstream>
#include <algorithm>
const int NMAX = 1e5+5;
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
int n, res[NMAX], v[NMAX], lst[NMAX], dp[NMAX], aib[NMAX], best, up[NMAX];
void update(int x, int ind)
{
for (; x <= n; x += (x&(-x)))
if (dp[ind] > dp[aib[x]])
aib[x] = ind; ///daca noul dp este mai mare, atunci e mai smecher noul dp decat cel vechi si il bagam in aib
}
int query(int x)
{
int mx = 0;
for (; x>0; x -= (x&(-x)))
if (dp[aib[x]] > dp[mx])
mx = aib[x]; ///daca cumva mx-ul querried este mai mic decat termenul ales, luam termenul ales
return mx;
}
int main()
{
in >> n;
for (int i = 1; i <= n; i++)
{
in >> v[i];
res[i] = lst[i] = v[i];
}
sort(lst+1, lst+1+n);
int lst_lg = 1;
for (int i = 2; i <= n; i++)
if (lst[i] != lst[lst_lg])
lst[++lst_lg] = lst[i]; ///ne creem o lista de termeni distinci din sirul n;
for (int i = 1; i <= n; i++)
v[i] = lower_bound(lst+1, lst+lst_lg+1, v[i])-lst; ///pentru fiecare v[i] ii gasim pozitia in lst for any reason
for (int i = 1; i <= n; i++)
{
up[i] = query(v[i]-1); ///cautam pe v[i]-1 why? aaa ca sa nu il luam pe v[i] insasi.
dp[i] = dp[up[i]]+1; ///up[i] reprezinta termenul precedent
update(v[i], i); ///tocmai ne-am updatat dp-ul, deci updatatam aib-ul
}
for (int i = 1; i <= n; i++)
if (dp[best] < dp[i])
best = i;
out << dp[best] << '\n'; ///best reprezinta ultimul termen
lst_lg = 0;
for (int i = best; i; i = up[i])
lst[++lst_lg] = res[i]; ///creem vectorul rezultat
for (int i = lst_lg; i > 0; i--)
out << lst[i] << ' ';
}