Cod sursa(job #1594274)

Utilizator andru47Stefanescu Andru andru47 Data 9 februarie 2016 12:59:17
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#define ub(x) (x&(-x))
#define pb push_back
using namespace std;
const int NMAX = 1000000;
vector <int> v,sol;
vector <int>::iterator it;
int N,a[NMAX],aib[NMAX],best[NMAX],soL = 0;
inline int quer(int poz)
{
    int maxy = 0;
    for (int i = poz; i>0; i-=ub(i))
        maxy=max(maxy,aib[i]);
    return maxy;
}
inline void updt(int poz,int val)
{
    for (int i = poz; i<=N; i+=ub(i))
        aib[i]=max(aib[i],val);
}
int main()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);
    scanf("%d\n", &N);
    for (int i = 1; i<=N; ++i)
    {
        scanf("%d", &a[i]);
        v.pb(a[i]);
    }
    sort(v.begin(),v.end());
    it=unique(v.begin(),v.end());
    v.resize(distance(v.begin(),it));
    for (int i = 1; i<=N; ++i)
        a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
    for (int i = 1; i<=N; ++i)
    {
        best[i]=quer(a[i]-1)+1;
        updt(a[i],best[i]);
        soL=max(soL,best[i]);
    }
    int right = N+1;
    for (int i = N; i; --i)
    {
        if (best[i]==soL&&a[i]<right)
        {
            sol.pb(a[i]);
            right = a[i] ;
            soL--;
        }
    }
    printf("%d\n", sol.size());
    for ( ; sol.size(); sol.pop_back())
        printf("%d ", v[sol.back()-1]);
    return 0;
}