Pagini recente » Cod sursa (job #2044604) | Cod sursa (job #385526) | Cod sursa (job #488917) | Cod sursa (job #1855585) | Cod sursa (job #1865719)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define nMax 100001
using namespace std;
int n, order[nMax], lMax, last[nMax], bestIndex;
typedef struct{
int number, poz;
} element;
typedef struct{
int bestL, index;
} nod;
typedef struct {
bool operator() (const element &x, const element &y) const{
return (x.number < y.number);
}
}comp;
vector <element> v;
vector <int> best_subString;
element y;
nod arb[4 * nMax + 66];
void read()
{
ifstream fin("scmax.in");
fin >> n;
int x;
for(int i = 1; i <= n; ++i){
fin >> x;
y.number = x;
y.poz = i;
v.push_back(y);
}
}
void normalize()
{
sort(v.begin(), v.end(), comp());
int same = 0;
order[v[0].poz] = 1;
for(int i = 1; i < n; ++i){
if(v[i].number == v[i - 1].number) same++;
order[v[i].poz] = i + 1 - same;
}
for(int i = 1; i < v.size(); ++i)
if(v[i].number == v[i - 1].number)
v.erase(v.begin() + i), i--; //sterg elementele care se repeta in v
}
void update(int node, int st, int dr, int a, int b)
{
if(st == dr){
arb[node].bestL = b;
arb[node].index = a;
}
else{
int mij = (st + dr) / 2;
if(a <= mij) update(2 * node, st, mij, a, b);
else update(2 * node + 1, mij + 1, dr, a, b);
if(arb[2 * node].bestL == arb[2 * node + 1].bestL)
arb[node].index = min(arb[2 * node].index, arb[2 * node + 1].index);
else
if(arb[2 * node].bestL > arb[2 * node + 1].bestL)
arb[node] = arb[2 * node];
else arb[node] = arb[2 * node + 1];
}
}
void query(int node, int st, int dr, int a, int b)
{
if(a <= st && dr <= b){
if(arb[node].bestL > lMax){
lMax = arb[node].bestL;
bestIndex = arb[node].index;
}
}
else{
int mij = (st + dr) / 2;
if(a <= st) query(2 * node, st, mij, a, b);
if(b > mij) query(2 * node + 1, mij + 1, dr, a, b);
}
}
void find_the_substring()
{
int next = arb[1].index;
for(int i = 1; i <= arb[1].bestL; ++i){
best_subString.push_back(v[next - 1].number);
next = last[next];
}
}
void solve()
{
for(int i = 1; i <= n; ++i){
lMax = 0;
if(order[i] > 1)
query(1, 1, v.size(), 1, order[i] - 1); // aflu lungimea maxima lMax a unui subsir care se termina pe unul din elementele mai mici decat cel curent
lMax++;
update(1, 1, v.size(), order[i], lMax); // actualizez lungimea maxima a subsirului care se termina cu elementul curent
last[order[i]] = bestIndex; // pe elementul curent l-am adaugat la subsirul terminat cu elementul bestIndex
}
find_the_substring();
}
void write()
{
ofstream fout("scmax.out");
fout << arb[1].bestL << '\n';
for(int i = best_subString.size() - 1; i >= 0; --i)
fout << best_subString[i] << ' ';
}
int main()
{
read();
normalize();
solve();
write();
return 0;
}