Cod sursa(job #1427252)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 1 mai 2015 20:00:22
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <cstdio>
#include <algorithm>
#include <vector>

#define nextp (p^(p&(p-1)))

#define Nmax 100005

using namespace std;
int N,V[Nmax],DP[Nmax],old[Nmax],daddy[Nmax];


class FenwickTree{
private:
    vector<int> range;
    int answer;
public:
    FenwickTree(){
        answer = 0;
    }
    void Resize(int k){
        range.resize(k + 1);
    }
    void Update(int pz,int ind){
        for(int p = pz; p <= N; p += nextp)
            if(DP[range[p]] < DP[ind])
                range[p] = ind;
    }
    int Query(int pz){
        answer = 0;
        for(int p = pz; p; p -= nextp)
            if(DP[answer] < DP[range[p]])
                answer = range[p];
        return answer;
    }
};
FenwickTree AIB;
vector<int> norm,sol;

void normalize()
{
    sort(norm.begin(),norm.end());
    for(int i = 1; i <= N; ++i)
        V[i] = lower_bound(norm.begin(),norm.end(),V[i]) - norm.begin() + 1;
}

void Read()
{
    scanf("%d",&N);
    AIB.Resize(N);
    for(int i = 1; i <= N; ++i){
        scanf("%d",&V[i]);
        old[i] = V[i];
        norm.push_back(V[i]);
    }
    normalize();
}

void Solve()
{
    int pzbest,best = -1,j;
    for(int i = 1; i <= N; ++i)
    {
        j = AIB.Query(V[i]-1);
        daddy[i] = j;
        DP[i] = DP[j] + 1;
        AIB.Update(V[i],i);
        if(DP[i] > best)
        {
            best = DP[i];
            pzbest = i;
        }
    }
    printf("%d\n",best);
    while(pzbest)
    {
        sol.push_back(old[pzbest]);
        pzbest = daddy[pzbest];
    }
    reverse(sol.begin(),sol.end());
    for(auto it : sol)
        printf("%d ",it);
}

int main()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);

    Read();
    Solve();

    return 0;
}