Pagini recente » Cod sursa (job #1893245) | Cod sursa (job #645411) | Cod sursa (job #2422241) | Cod sursa (job #1241969) | Cod sursa (job #670158)
Cod sursa(job #670158)
//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>
#include<cassert>
#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]<<' ';
}
inline int bin_search (int val)
{
int st=-1,dr=Q.size()-1,m;
while(dr-st>1)
{
m = ((unsigned int)st + (unsigned int)dr) >> 1;
if(v[Q[m]] < val)
st=m;
else
dr=m;
}
// if (dr == Q.size() || A[dr] != x) // cand ultimul element din sir e mai mic decat x, st = A.length - 1 si dr = A.length
// return -1; // sau cand dr este undeva in interiorul sirului, A[st] < x < A[dr]
// else //x e in sir
return dr;
}
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 p = bin_search(v[i]);
assert(p>=0);
if (v[i] < v[Q[p]])
{
if (p > 0)
prev[i] = Q[p-1];
Q[p] = i;
}
//varianta cu upper_bound: //problema e ca upper bound merge doar pt subsir crescator (nestrict, cu <=)
// vector<int>::iterator it = upper_bound(Q.begin(), Q.end(), v[i], cmp); //
// if(it != Q.begin() && v[*(it-1)] == v[i]) //upper_bound face <= cumva deci trebuie sa verificam si sa nu fie elemente egale
// continue;
// int _pit=it-Q.begin();
// 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;
}