Pagini recente » Cod sursa (job #3125788) | Calibrare limite de timp | Cod sursa (job #2866877) | Cod sursa (job #2875789) | Cod sursa (job #347115)
Cod sursa(job #347115)
/* L.I.S. cu Arbori indexati binari
O(N * log N)
Intra fara parsare, spre deosebire de Arbori de intervale
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
int sir[100010];
int S[100010];
int BIT[100010];
int pozF;
int SandD[100010];
int n;
int bst[100010];
int i;
int maxG;
int CautBin(int val)
{
int st = 1;
int dr = n;
while (st <= dr)
{
if (SandD[(st + dr) / 2] > val) dr = (st + dr) / 2 - 1;
else
if (SandD[(st + dr) / 2] < val) st = (st + dr) / 2 + 1;
else
return (st + dr) / 2;
}
}
int Query(int p)
{
int max = 0;
while (p > 0)
{
if (max < BIT[p]) max = BIT[p];
p -= (p & -p);
}
return max;
}
int Update(int p, int maxL)
{
while (p <= n)
{
if (maxL > BIT[p]) BIT[p] = maxL;
p += (p & -p);
}
}
int PrintSol(int now, int val)
{
if (bst[now] > 1)
{
for(i = now; bst[i] != val; i--);
PrintSol(i, val - 1);
}
printf("%d ",SandD[sir[now]]);
}
int main()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
scanf("%d",&n);
for(int i = 1; i <= n ; i++)
{
scanf("%d",&sir[i]);
S[i] = sir[i];
}
sir[0] = n;
sort(S + 1, S + n + 1);
for(int i = 1; i <= n ; i++)
{
if (S[i] != S[i-1]) SandD[++SandD[0]] = S[i];
}
for(int i = 1; i <= n; i++)
{
sir[i] = CautBin(sir[i]);
}
n = SandD[0];
for(int i = 1; i <= sir[0]; i++)
{
int best = 0;
if (sir[i] > 1)
best = Query(sir[i] - 1);
bst[i] = best + 1;
Update(sir[i],best + 1);
}
for(int i = 1; i <= sir[0]; i++)
{
if (maxG < bst[i])
{
maxG = bst[i];
pozF = i;
}
}
printf("%d\n", maxG);
PrintSol(pozF, maxG - 1);
}