Cod sursa(job #1151954)

Utilizator beldeabogdanBogdan Beldea beldeabogdan Data 24 martie 2014 14:18:25
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <cstdio>
#include <algorithm>
#define nmax 100005
#define lsb(a) (a&(-a))
#define maxim(a,b) (a>b)?(a):(b)
using namespace std;

int arb[3*nmax];
int v[nmax],a[nmax],vn[nmax],l[nmax],prec[nmax];
int n,p,lmax,lmp;

inline int cautbin(int v) {
    int s = 1,f = p;
    while (s <= f) {
        int mij = (s+f)/2;
        if (v < a[mij]) f = mij-1;
        else if (v == a[mij]) return mij;
        else s = mij+1;
    }
    return s;
}

inline int query(int pos) {
    int r=0,mx = 0;
    while (pos > 0) {
        if (l[arb[pos]] > mx) {
            mx = l[arb[pos]];
            r = arb[pos];
        }
        pos -= lsb(pos);
    }
    return r;
}

inline void update(int pos,int val) {
    while (pos <= n) {
        if (l[arb[pos]] < l[val]) arb[pos] = val;
        pos += lsb(pos);
    }
}

void print(int p) {
    int k = 0,s[nmax];
    while (p != 0) {
        s[++k] = a[vn[p]];
        p = prec[p];
    }
    for (int i=k;i>=1;i--) printf("%d ",s[i]);
}

int main() {
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);
    scanf("%d",&n);
    for (register int i=1;i<=n;i++) {
        scanf("%d",&v[i]);
        a[i] = v[i];
    }
    sort(a+1,a+n+1);
    for (register int i=1;i<=n;i++) if (a[i] != a[i+1]) a[++p] = a[i];
    for (register int i=1;i<=n;i++) vn[i] = cautbin(v[i]);
    for (register int i=1;i<=n;i++) {
        int q = query(vn[i]-1);
        l[i] = l[q]+1;
        update(vn[i],i);
        prec[i] = q;
        if (lmax < l[i]) lmax = l[i],lmp=i;
    }
    printf("%d\n",lmax);
    print(lmp);
    printf("\n");
    return 0;
}