Pagini recente » Cod sursa (job #1098139) | Cod sursa (job #853648) | Cod sursa (job #2131821) | Cod sursa (job #1189411) | Cod sursa (job #2567252)
#include <bits/stdc++.h>
#define LSB(x) ((-x) & x)
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
int n, aib[100010],///cel mai mic element de oridin i se afla in aib[i]
lst[100010], h = 1,///pt a calcula cati termeni unici sunt
Res[100010],a[100010], dp[100010], poz[100010], bst;
void update(int x, int ind)
{
for(int i = x;i <= n;i += LSB(i))
if(dp[ind] > dp[aib[i]]) aib[i] = ind;
}
int query(int x)
{
int max = 0;
for(int i = x;i >= 1;i -= LSB(i))
if(dp[aib[i]] > dp[max]) max = aib[i];
return max;
}
void afis(int x)
{
if(x == 1)
{
out << 1 << " ";
return;
}
afis(poz[x]);
out << x << " ";
}
int main()
{
in >> n;
for(int i = 1;i <= n;i++)
{
in >> a[i];
Res[i] = lst[i] = a[i];
}
sort(lst + 1,lst + n + 1);
for(int i = 2;i <= n;i++)
if(lst[i] != lst[h])
lst[++h] = lst[i];
///unde se afla a[i] in lst[i]
for(int i = 1;i <= n;i++)
a[i] = lower_bound(lst + 1,lst + h + 1, a[i]) - lst;
for(int i = 1;i <= n;i++)
{
///aflam pozitia celui mai mare element inaintea lui din sirul ordonat
poz[i] = query(a[i] - 1);
///daca avem pozitie actualizam dinamica sau punem unu
dp[i] = dp[poz[i]] + 1;
///adaugam pozitia elementului in aib din sirul normal
update(a[i], i);
}
for(int i = 1;i <= n;i++)
if(dp[bst] < dp[i]) bst = i;
out << dp[bst] << '\n';
h = 0;
///daca vreau elementele
for(int i = bst;i >= 1;i = poz[i])
lst[++h] = Res[i];
for(int i = h;i >= 1;i--)
out << lst[i] << " ";
///daca vreau pozitiile
///afis(bst);
return 0;
}