Cod sursa(job #670140)

Utilizator laurionLaurentiu Ion laurion Data 28 ianuarie 2012 15:06:27
Problema Subsir crescator maximal Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
//scmax cu upper_bound by Laur Ion
//Complexitate: O(N lg K)  | unde K e lungimea scmax  (cautarea binara este facuta pe Q (nu v) a carui lungime este mereu <= K => O(lg K) complexitate)
#include<cstdio>
#include<iostream>
#include<fstream>
#include<vector>
#include<cstring>
#include<string>
#include<sstream>
#include<iterator>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<algorithm>

#define filein  "scmax.in"
#define fileout "scmax.out"

using namespace std;

ifstream fin(filein);
ofstream fout(fileout);

int n;
//vector<int> G[100000+10];
#define NMax 100005

int v[NMax], prev[NMax];
vector<int> Q; //vector de pozitii ale scmax

bool cmp(int val, int poz)
{
    return val < v[poz];
}
inline void afis(int poz)
{
    if(poz == 0) {
        return;
    }
    afis(prev[poz]);
    fout<<v[poz]<<' ';
}
int main()
{
    fin>>n;
    for(int i=1; i<=n; ++i)
        fin>>v[i];

    Q.push_back(1);
//    memset(prev,0xff,sizeof(prev));
    for(int i=2; i<=n; ++i) {
        if (v[i] > v[Q.back()]) {   //daca elementul curent e mai mare decat ultimul element a scmax curente (v[Q.back])
            prev[i] = Q.back();     //se adauga la capatul lui Q si se continua
            Q.push_back(i);
            continue;
        }
        //cauta cel mai mic element referentiat de Q care e mai mare decat v[i]
//        int st,dr;
//        for (st = 0, dr = Q.size()-1; st < dr;) 
//        {
//			int m = (st + dr) / 2;
//			if (v[Q[m]] < v[i]) st=m+1; else dr=m;
//        }
//		if (v[i] < v[Q[dr]]) 
//        {
//			if (dr > 0) 
//                prev[i] = Q[dr-1];
//			Q[dr] = i;
//		}
        vector<int>::iterator it = upper_bound(Q.begin(), Q.end(), v[i], cmp);
        if(v[i]<v[*it]) {
            if(it != Q.begin())
                prev[i] = *(it-1);
            *it = i;
        }
    }

    fout<<Q.size()<<'\n';

    afis(Q.back());
    fout<<'\n';

    fout.close();
    return 0;
}