Cod sursa(job #857720)

Utilizator razvan.popaPopa Razvan razvan.popa Data 18 ianuarie 2013 11:57:47
Problema Subsir crescator maximal Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 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 mx(a,b) Bst[a] > Bst[b] ? a : b
#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 <= l && r <= b)
       return AI[nod];

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

    return mx(r1,r2);
}


void update(int nod, int l, int r, int pos, int x){
    if(l == r){
        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);

    AI[nod] = mx(AI[2*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;

        if(val[i] != 1)
           x = cauta(1, 1, N, 1, val[i] - 1);
        else
           x = 0;

        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;
}