Pagini recente » Cod sursa (job #1388804) | Cod sursa (job #1617653) | Cod sursa (job #1711005) | Cod sursa (job #1656489) | Cod sursa (job #2104939)
/// LONGEST INCREASING SUBSEQUENCE
#include <iostream>
#include <fstream>
#include <utility>
#include <algorithm>
#include <map>
#include <sstream>
#include <memory>
#include <cstring>
#define NMax 100001
///#define f cin
///#define g cout
using namespace std;
ifstream f("scmax.in");
ofstream g("scmax.out");
int n, a[NMax], temp[NMax], sol[NMax], ans, realSol[NMax], foo;
int topmiddle(int a[NMax], int temp[NMax], int end, int key)
{
int start = 0;
int middle;
int len = end;
while(start <= end)
{
middle = (start + end) / 2;
if(a[temp[middle]] < key && key <= a[temp[middle + 1]]) return middle + 1; /// daca cheia e intre a de mijlocul lui T si mijlocul lui T + 1 returnezi mijlocul + 1
else if(a[temp[middle]] < key) start = middle + 1; /// altfel continui binary search..
else end = middle - 1;
}
return -1;
}
int main()
{
f >> n;
for(int i = 1; i <= n; ++i)
{
f >> a[i];
sol[i] = -1;
}
for(int i = 1; i <= n; ++i)
{
if(a[temp[1]] > a[i]) temp[1] = i;
else if(a[temp[ans]] < a[i]) /// daca a[i] e mai mare decat ultima valoare din T atunci o bagi a ultima valoare in T
{
++ans;
temp[ans] = i;
sol[temp[ans]] = temp[ans - 1];
}
else /// faci binary search sa gasesti maximul din elementele din mijloc
{
int index = topmiddle(a, temp, ans, a[i]);
temp[index] = i;
sol[temp[index]] = temp[index - 1];
}
}
g << ans << '\n';
int index = temp[ans];
while(index != -1)
{
realSol[++foo] = a[index];
index = sol[index];
}
for(int i = foo; i >= 1; --i)
g << realSol[i] << " ";
return 0;
}