Pagini recente » Cod sursa (job #2667607) | Cod sursa (job #1492174) | Cod sursa (job #1467034) | Cod sursa (job #106055) | Cod sursa (job #1894233)
#include <fstream>
#include <algorithm>
using namespace std;
#define valMax 100005
struct nod{
int ls,ld,ea;
nod *st,*dr;
};
int n,si[valMax], // sirul initial nemodif
s[valMax], // sirul normat
id[valMax], // index pentru normare
l[valMax], // lungimea maxima subsir cu elemente pana la poz curenta
ea[valMax], // index element anterior elementului curent in subsir
ss[valMax]; // subsirul de lunfime maxima
ifstream in("scmax.in");
ofstream out("scmax.out");
nod *arbore(int st,int dr){
nod *nc;
nc=new nod;
nc->ls=st;
nc->ld=dr;
nc->ea=0;
if(st==dr){
nc->st=NULL;
nc->dr=NULL;
}
else{
int m=(st+dr)/2;
nc->st=arbore(st,m);
nc->dr=arbore(m+1,dr);
}
return nc;
}
int cautare(nod *nc,int val){
int jMax=0;
if(nc!=NULL){
if(nc->ls<=val && val<=nc->ld){
if(l[jMax]<l[nc->ea])
jMax=nc->ea;
int m=(nc->ls+nc->ld)/2;
if(val<=m){
int j=cautare(nc->st,val);
if(l[jMax]<l[j])
jMax=j;
}
else{
int j=cautare(nc->dr,val);
if(l[jMax]<l[j])
jMax=j;
}
}
else{
if(nc->ld<=val)
if(l[jMax]<l[nc->ea])
jMax=nc->ea;
}
}
return jMax;
}
void actualizare(nod *nc,int ls,int iVal){
if(nc!=NULL){
if(ls<=nc->ls){ // intervalul nodului inclus in intervalul de actualizat
if(l[nc->ea]<l[iVal]) // actualizare nod curent
nc->ea=iVal;
}
else{
if(nc->ls<ls && ls<nc->ld){ // intervalul nodului are zona de inceput in afara intervalului de actualizat
int m=(nc->ls+nc->ld)/2;
if(ls<=m){
actualizare(nc->st,ls,iVal);
actualizare(nc->dr,ls,iVal);
}
else{
actualizare(nc->dr,ls,iVal);
}
}
else{
actualizare(nc->dr,ls,iVal);
}
}
}
}
int main()
{
// citire
in>>n;
int vMax=0;
for (int i = 1; i <= n; i++){
in>>s[i];
si[i]=id[i]=s[i];
}
//normare sir
sort(id+1,id+n);
int j=1;
for (int i = 1; i <= n; i++){
if(id[i]!=id[j]){
id[j]=id[i];
j++;
}
}
for (int i=1;i<=n; i++)
s[i] = lower_bound(id+1, id+j, s[i])-id;
vMax=j;
nod *r=NULL;
r=arbore(1,vMax);
// cautare subsir de lungime maxima
for (int i = 1; i <= n; i++){
int jMax=cautare(r,s[i]);
l[i]=l[jMax]+1;
ea[i]=jMax;
actualizare(r,s[i]+1,i);
}
// alegere subsir de lungime maxima din cele maxime ale fiecarui nivel
// deoarece in D[] avem subsirul de lungime maxima care se termina cu poz curenta
// si pot exista cazuri in care pe ultima pozitie sa avem un subsir mai scurt
// ex: 1 3 5 8 2
int iMax=0;
for (int i = 1; i <= n; i++)
if (l[iMax] < l[i])
iMax = i;
//afisare
out<<l[iMax]<<'\n';
for (int j=l[iMax],i = iMax; i>0;i=ea[i])
ss[j--]=si[i];
for (int i = 1; i<=l[iMax]; i++)
out<<ss[i]<<' ';
out<<'\n';
return 0;
}