Cod sursa(job #976182)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 22 iulie 2013 18:13:59
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <fstream>
#include <algorithm>
#include <vector>

#define In "scmax.in"
#define Out "scmax.out"
#define Nmax 100002
#define f(x) ((x)&(-(x)))
#define max(a,b) ((a)>(b)?(a):(b))

using namespace std;

int Sol[Nmax], N, dp[Nmax], Last[Nmax], a[Nmax], v[Nmax], A[Nmax], sol;

class Aib
{
    public:
    inline void Update(const int poz,const int val)
    {
        for(int i = poz;i <= N;i += f(i))
            aib[i] = dp[aib[i]] < dp[val]? val: aib[i];
    }
    inline int Query(const int x)
    {
        int i, ret = 0;
        for(i = x; i; i-= f(i))
            ret = dp[aib[i]] < dp[ret]? ret: aib[i];
        return ret;
    }
    public :int aib[Nmax];
};
Aib AIB;
inline void Read()
{
    ifstream in(In);
    in>>N;
    for(int i = 1;i <= N;++i)
    {
        in>>A[i];
        a[i] = A[i];
    }
    in.close();
}
inline void Normalization()
{
    int i;
    sort(A+1,A+N+1);
    for(i = 1;i <= N; ++i)
        v[i] = upper_bound(A+1,A+N+1,a[i])-A-1;
}

inline void Solve()
{
    int i, j;
    for(i=1;i<=N;++i)
    {
        j = AIB.Query(v[i]-1);
        dp[i] = 1+dp[j];
        Last[i] = j;
        AIB.Update(v[i],i);
        if(dp[i]>dp[sol])
            sol = i;
    }
}

inline void Write()
{
    int i,n = dp[sol];
    vector<int>rez;
    ofstream out(Out);
    out<<n<<"\n";
    for(i = 1 ;i <= n; ++i)
    {
        rez.push_back(a[sol]);
        sol = Last[sol];
    }
    for(vector<int>::reverse_iterator it=rez.rbegin();it!=rez.rend();++it)
        out<<*it<<" ";
    out<<"\n";
    out.close();
}

int main()
{
    Read();
    Normalization();
    Solve();
    Write();
    return 0;
}