Pagini recente » Cod sursa (job #2621626) | Cod sursa (job #3291411) | Cod sursa (job #2265507) | Cod sursa (job #939088) | Cod sursa (job #1005423)
#include <fstream>
#include <algorithm>
#define N 100010
int n;
int data[N];
int pos[N];
int left[N];
int aib[N];
int best[N];
int pred[N];
int res[N];
std::pair<int, int> sorted[N];
int query(int p)
{
int ret = aib[p];
while (p)
{
if (best[aib[p]] > best[ret])
ret = aib[p];
p &= p - 1;
}
return ret;
}
void update(int p, int bp)
{
while (p <= n)
{
if (best[aib[p]] < best[bp])
aib[p] = bp;
p += p & (-p);
}
}
bool comp(std::pair<int, int> a, std::pair<int, int> b)
{
return a.first < b.first;
}
void read_data(const char *filename)
{
std::ifstream in(filename);
in >> n;
for (int i = 0; i < n; ++i)
{
in >> data[i];
sorted[i] = std::make_pair(data[i], i);
}
in.close();
}
void prepare()
{
std::sort(sorted, sorted + n, comp);
for (int i = 0; i < n; ++i)
pos[sorted[i].second] = i;
left[0] = 0;
for (int i = 1; i < n; i++)
if (sorted[i].first == sorted[i - 1].first)
left[i] = left[i - 1];
else
left[i] = i;
for (int i = 1; i <= n; i++)
aib[i] = i - 1;
for (int i = 0; i < n; ++i)
best[i] = 0;
}
void alg()
{
best[pos[0]] = 1;
update(pos[0] + 1, pos[0]);
pred[pos[0]] = -1;
for (int i = 1; i < n; i++)
{
if (left[pos[i]] == 0)
{
best[pos[i]] = 1;
pred[pos[i]] = -1;
}
else
{
int q = query(left[pos[i]]);
best[pos[i]] = best[q] + 1;
pred[pos[i]] = q;
}
update(pos[i] + 1, pos[i]);
}
}
void resp(const char *filename)
{
std::ofstream out(filename);
int g = 0;
for (int i = 1; i < n; i++)
if (best[i] >= best[g])
g = i;
out << best[g] << "\n";
n = 0;
while (g != -1)
{
res[n++] = g;
g = pred[g];
}
while (n--)
out << sorted[res[n]].first << " ";
out << "\n";
out.close();
}
int main()
{
read_data("scmax.in");
prepare();
alg();
resp("scmax.out");
}