Pagini recente » Cod sursa (job #842342) | Cod sursa (job #1301759) | Cod sursa (job #1111125) | Cod sursa (job #1916463) | Cod sursa (job #3352754)
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
int v[100001];
int last[100001];//cea mai mica valdin v[i] cu care se poate termina o subsecv de lung len
int lung[100001];//lung celui mai lun subsir care se term in poz i
int n;
int maxlen;
int prev[100001];//ce poz in v are predecesorul din last al lui i
void afis(int i){
if(prev[i]>0)//daca se extine familia
afis(prev[i]);//aici retin pozitia
fout<<v[i]<<" ";//afisez valoarea
}
int caut_bin(int val){
int stg=0;
int dr=maxlen;//sa fac doar pana la last ul pe care l am precalculat
while(stg<=dr){
int mij=(stg+dr)/2;
if(v[last[mij]] < val && v[last[mij+1]] >= val){
return mij;
}
else if(v[last[mij+1]] < val){
stg=mij+1;
}
else{
dr=mij-1;
}
}
return maxlen;
}
int main()
{
fin >> n;
for (int i = 1; i <= n; i++) {
fin >> v[i];
}
maxlen=1;
lung[1]=1;
last[1]=1;
last[0]=0;
for(int i=2;i<=n;i++){
int poz=caut_bin(v[i]);//unde l pot baga pe v[i]
prev[i]=last[poz];//poz elem anterior in subsir (in last[poz] am pozitia elem din subsir de pe pozitia poz, adica penultimul din subsirul crnt)
lung[i]=poz+1;//lung max devine poz+1( l am bagat pe v[i] gen)
last[poz+1]=i;//actualizez pozitia in last i (pe pozitia poz+1 vine v[i])
maxlen=max(maxlen,poz+1);//poz pana la care am completat in last pana acum
}
//vad care e lung max al subsirului si pozitia din v la care se termina
int poz_fin=0;
int lung_max=0;
for(int i=1;i<=n;i++){
if(lung[i]>lung_max){
lung_max=lung[i];
poz_fin=i;
}
}
fout<<lung_max<<'\n';
afis(poz_fin);
return 0;
}