Pagini recente » Cod sursa (job #722444) | Cod sursa (job #1813631) | Cod sursa (job #373676) | Cod sursa (job #2656056) | Cod sursa (job #670140)
Cod sursa(job #670140)
//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;
}