Pagini recente » Cod sursa (job #1924592) | Cod sursa (job #3201577) | Cod sursa (job #2841116) | Cod sursa (job #2118866) | Cod sursa (job #1982419)
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream in("sdo.in");
ofstream out("sdo.out");
#define ll long long
#define pb push_back
const int NMax = 3e6 + 5;
// solutie O(n + klogk)
int N,K,nrHeap;
int v[NMax],heap[NMax];
// v = vectorul initial, care va fi organizat intr-o structura de heap
// heap = un heap ce retine valoarea minima si compara doua elemente heap[i],heap[j]
// folosind valoarea lor din vectorul v (ex.: v[heap[i]] < v[heap[j]]),
// heap[i] reprezentand indexul unui element din v
void siftFirst(int,int);
// siftFirst(i,dim) muta nodul i in jos pana la pozitia corespunzatoare in vectorul v,
// care are dim elemente
void siftSecond(int,int);
// siftSecond(i,dim) muta nodul i in jos pana la pozitia corespunzatoare in vectorul heap,
// care are dim elemente
void percolate(int);
// percolate(i) muta nodul i in sus pana la pozitia corespunzatoare in vectorul heap,
// care are dim elemenete
int main() {
in>>N>>K;
for (int i=1;i <= N;++i) {
in>>v[i];
}
// buildHeap
// se transforma v intr-o structura de heap
for (int i=N/2;i > 0;--i) {
siftFirst(i,N);
}
// se introduce elementul minim din v (v[1]) in heap,
// iar la fiecare iteratie se gaseste urmatorul element minim din v
// si se introduc fii acestui minim in heap
// pentru ca ele reprezinta un posibil urmator minim
heap[++nrHeap] = 1;
for (int c=1;c < K;++c) {
int node = heap[1];
swap(heap[1],heap[nrHeap]);
--nrHeap;
siftSecond(1,nrHeap);
// acest minim este scos doarece nu ne intereseaza primele K-1 minime
// se introduc fii
int fs = node*2,ss = fs+1;
if (fs <= N) {
heap[++nrHeap] = fs;
percolate(nrHeap);
}
if (ss <= N) {
heap[++nrHeap] = ss;
percolate(nrHeap);
}
}
// acum, heap[1] va fi a K-a valoare minima din v
out<<v[heap[1]]<<'\n';
in.close();out.close();
return 0;
}
void siftFirst(int node,int dim) {
int son = 0;
do {
son = 0;
int fs = node*2,
ss = node*2 + 1;
if (fs <= dim) {
son = fs;
if (ss <= dim && v[ss] < v[son]) {
son = ss;
}
}
if (son && v[son] < v[node]) {
swap(v[node],v[son]);
node = son;
}
else {
son = 0;
}
}
while (son);
}
void siftSecond(int node,int dim) {
int son = 0;
do {
son = 0;
int fs = node*2,
ss = node*2 + 1;
if (fs <= dim) {
son = fs;
if (ss <= dim && v[heap[ss]] < v[heap[son]]) {
son = ss;
}
}
if (son && v[heap[son]] < v[heap[node]]) {
swap(heap[node],heap[son]);
node = son;
}
else {
son = 0;
}
}
while (son);
}
void percolate(int node) {
int dad = node/2;
while (node != 1 && v[heap[node]] < v[heap[dad]]) {
swap(heap[node],heap[dad]);
node = dad;
dad = node/2;
}
}