Cod sursa(job #993417)

Utilizator harababurelPuscas Sergiu harababurel Data 3 septembrie 2013 19:30:53
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define nmax 100005
using namespace std;

vector <pair <int, int> > ord;
vector <int> sol;

int H[3*nmax], v[nmax], pos[nmax], pos2[nmax], best[nmax];
int n, ret, bestestBest;

void update(int node, int lo, int hi, int pos, int val) {
    if(lo == hi) {
        H[node] = val;
        return;
    }

    int mid = (lo + hi) >> 1;
    if(pos <= mid) update(2*node, lo, mid, pos, val);
    else           update(2*node+1, mid+1, hi, pos, val);

    H[node] = max(H[2*node], H[2*node+1]);
}

void query(int node, int lo, int hi, int a, int b) {
    if(b < a) return;
    if(a <= lo && hi <= b) {
        ret = max(ret, H[node]);
        return;
    }

    int mid = (lo + hi) >> 1;
    if(a <= mid) query(2*node, lo, mid, a, b);
    if(b  > mid) query(2*node+1, mid+1, hi, a, b);
}


int main() {
    ifstream f("scmax.in");
    ofstream g("scmax.out");

    f>>n;
    for(int i=0; i<n; i++) {
        f>>v[i];
        ord.push_back(make_pair(v[i], i));
    }
    sort(ord.begin(), ord.end());

    for(int i=0; i<ord.size(); i++) {
        pos[ord[i].second] = i;         //valoarea aflata initial pe pozitia <ord[i].second> se afla acum pe <i>
        pos2[ord[i].second] = i;
        if(i > 0 && ord[i].first == ord[i-1].first) pos2[ord[i].second] = pos2[ord[i-1].second];
    }

    for(int i=0; i<n; i++) {

        ret = 0;
        query(1, 0, n, 0, pos2[i]-1);
        best[i] = ret + 1;

        update(1, 0, n, pos[i], best[i]);
    }


    //for(int i=0; i<n; i++) cout<<pos[i]<<" "; cout<<"\n";
    //for(int i=0; i<n; i++) cout<<pos2[i]<<" "; cout<<"\n\n";

    for(int i=0; i<n; i++) bestestBest = max(bestestBest, best[i]); //cout<<best[i]<<" "; cout<<"\n";

    g<<bestestBest<<"\n";

    for(int i=n-1; i>=0; i--)
        if(best[i] == bestestBest) {
            sol.push_back(v[i]);
            bestestBest--;
        }

    for(int i=sol.size()-1; i>=0; i--) g<<sol[i]<<" ";
    g<<"\n";


    return 0;
}