Cod sursa(job #1855159)

Utilizator TimoteiCopaciu Timotei Timotei Data 23 ianuarie 2017 14:45:53
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#define zeros(x) ( (x ^ (x - 1)) & x )

using namespace std;
int n, v[100005], order[100005], maxL = 0, poz_maxL, best[100005], aib[100005], sol[100005],  poz[100005];
typedef struct{
  int number, poz;
} element;
element a[100005];

/*inline int comp(element x, element y)
{
    return x.number < y.number;
}*/
typedef struct {
   bool operator() (const element &x, const element &y) const{
     return (x.number < y.number);
   }
}comp;
int update(int x, int ind)
{
    for(; x <= n; x += zeros(x))
        if(best[ind] > best[aib[x]])
            aib[x] = ind;
}
int query(int x)
{
    int mx = 0;
    for(; x >= 1; x -= zeros(x)){
        if(best[aib[x]] > best[mx])
            mx = aib[x];
    }
    return mx;
}
void read()
{
    ifstream fin("scmax.in");
    fin >> n;
    for(int i = 1; i <= n; ++i){
        fin >> v[i];
        a[i].number = v[i];
        a[i].poz = i;
    }
}
void normalize()
{
    int same = 0;
    sort(a + 1, a + n + 1, comp());
    order[a[1].poz] = 1;
    for(int i = 2; i <= n; ++i){
        if(a[i].number == a[i - 1].number) same++;
        order[a[i].poz] = i - same;
    }
}
void solve()
{
    for(int i = 1; i <= n; ++i){
        poz[i] = query(order[i] - 1);
        best[i] = best[poz[i]] + 1;
        update(order[i], i);
        if(best[i] > maxL){
            maxL = best[i];
            poz_maxL = i;
        }
    }
}
void write()
{
    ofstream fout("scmax.out");
    fout << maxL << '\n';
    int h = 0;
    for(int i = poz_maxL; i; i = poz[i])
        sol[++h] = v[i];
    for(int i = h; i >= 1; --i)
        fout << sol[i] << ' ';
}
int main()
{
    read();
    normalize();
    solve();
    write();
    return 0;
}