Cod sursa(job #857711)

Utilizator razvan.popaPopa Razvan razvan.popa Data 18 ianuarie 2013 11:36:40
Problema Subsir crescator maximal Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include<iostream>
#include<iostream>
#include<fstream>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#define INF (1 << 30)
#define pb push_back
#define mkp make_pair
#define pii pair<int, int>
#define ll long long
#define nxt (*it)
#define type int
#define FORi(i,a,b)\
   for(int i=a; i<=b; ++i)
#define FORr(g)\
   for(vector<type>::reverse_iterator it=g.rbegin(); it!=g.rend(); ++it)
#define FOR(g)\
   for(vector<type>::iterator it=g.begin(); it!=g.end(); ++it)
#define infile "scmax.in"
#define outfile "scmax.out"
#define nMax 100005
using namespace std;

ofstream g(outfile);

int a[nMax], val[nMax];

vector < int > b;

int Bst[nMax], Prev[nMax];

int AI[4 * nMax];

int N, iSol;


void read(){
    ifstream f(infile);

    f >> N;

    FORi(i,1,N){
       f >> a[i];
       b.pb(a[i]);
    }

    f.close();
}


int cauta(int nod, int l, int r, int a, int b){
    if(a > b)
      return 0;

    if(a <= l && r <= b)
       return AI[nod];

    int x = 0, y = 0, m = (l + r)/2;
    if(a <= m)
       x = cauta(2*nod, l, m, a, b);
    else
       y = cauta(2*nod+1, m+1, r, a, b);

    if(Bst[x] > Bst[y])
       return x;
    return y;
}


void update(int nod, int l, int r, int pos, int x){
    if(l == r){
        if(Bst[AI[nod]] < Bst[x])
           AI[nod] = x;
        return;
    }

    int m = (l + r)/2;
    if(pos <= m)
       update(2*nod, l, m, pos, x);
    else
       update(2*nod+1, m+1, r, pos, x);

    if(Bst[AI[2*nod]] > Bst[AI[2*nod+1]])
       AI[nod] = AI[2*nod];
    else
       AI[nod] = AI[2*nod+1];
}


void solve(){
    sort(b.begin(), b.end());

    FORi(i,1,N)
       val[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;

    FORi(i,1,N){
        int x = cauta(1, 1, N, 1, val[i] - 1);

        Bst[i] = Bst[x] + 1;
        Prev[i] = x;

        if(Bst[iSol] < Bst[i])
           iSol = i;

        update(1, 1, N, val[i], i);
    }
}

void print(int x){
    if(!x){
      g << Bst[iSol] << '\n';
      return;
    }

    print(Prev[x]);

    g << a[x] << " ";
}

int main(){
    read();
    solve();

    print(iSol);
    g.close();

    return 0;
}