Cod sursa(job #2578198)

Utilizator 1chiriacOctavian Neculau 1chiriac Data 10 martie 2020 18:48:28
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include <bits/stdc++.h>

using namespace std;
#define DIM 10000
	
char buff[DIM];
	
int poz=0;
	
 
	
void citeste(int &numar)
	
{
	
     numar = 0;
	
     //cat timp caracterul din buffer nu e cifra ignor      
	
     while (buff[poz] < '0' || buff[poz] > '9')     
	
          //daca am "golit" bufferul atunci il umplu
	
          if (++poz == DIM) 
	
               fread(buff,1,DIM,stdin),poz=0;
	
     //cat timp dau de o cifra recalculez numarul          
	
     while ('0'<=buff[poz] && buff[poz]<='9')
	
     {
	
          numar = numar*10 + buff[poz] - '0';
	
          if (++poz == DIM) 
	
               fread(buff,1,DIM,stdin),poz=0;               
	
     }     
	
}
int n,v[100003],aib[100003],a[100003],sol[100003],maxim,best[100003],a1[100005];
int cb (int nr) {
	int i=0,step=1;
	for(;(step<<1)<=n;step<<=1);
	for(;step>0;step>>=1)
		if(i+step<=n && a[i+step]<nr)
			i+=step;
	return i+1;
}
int lsb (int nr) {
	return (nr & (-nr));
}
void updatee (int poz, int val ) {
	while(poz<=n) {
		if(best[val]>best[aib[poz]])
			aib[poz]=val;
		poz=poz+lsb(poz);
	}
}
int querrys (int dr) {
	maxim=0;
	while(dr>0) {
		if(best[aib[dr]]>best[maxim])
			maxim=aib[dr];
		dr=dr-lsb(dr);
	}
	return maxim;
}
int main () {
	int poz1;
	freopen("scmax.in","r",stdin);
	freopen("scmax.out","w",stdout);
	citeste(n);
	for(int i=1;i<=n;++i)
		citeste(v[i]),a[i]=v[i],a1[i]=v[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;++i)
		v[i]=cb(v[i]);
	for(int i=1;i<=n;++i) {
		best[i]=best[querrys(v[i]-1)]+1;
		updatee(v[i],i);
	}
	maxim=-1;poz=0;
	for(int i=1;i<=n;++i)
		if(best[i]>maxim)
			maxim=best[i],poz1=i;
	printf("%d\n", maxim);
	sol[maxim]=a1[poz1];
	for(int i=poz1-1;i>0 && maxim>0;--i)
		if(best[i]==maxim-1 && a1[i]<sol[maxim])
			sol[--maxim]=a1[i];
	for(int i=1;i<=best[poz1];++i)
		printf("%d ", sol[i]);
	return 0;
}