Cod sursa(job #1007780)

Utilizator vlad.doruIon Vlad-Doru vlad.doru Data 9 octombrie 2013 18:51:41
Problema Statistici de ordine Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.46 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <climits>
#include <algorithm>
 
using namespace std;
 
ifstream in("sdo.in");
ofstream out("sdo.out");
 
const int N = 5000000;
 
int v[N];
 
/* Find sqrt in logarithmic time */
int sqrt(int x) {
     
    int step, i;
 
    for (step = 1; step < x; step <<= 1);
 
    for (i = 0; step; step >>= 1) {
        if ( (double)(i + step) * (double)(i + step) <= x) 
            i += step;
    }
 
    return i;
 
}

/* Integer vector */
class iVector {
public:
    iVector();
    int  push_back(int x);
    int  size();
    void set_size(int x);
    int* data();
    ~iVector();
private:
    int _size;
    int _used;
    int *_data;
    /* data */
};

iVector::iVector() : _size(1024), _used(0) {
    if (_size)
        _data = new int[_size];
}

iVector::~iVector() {
    delete _data;
}

int iVector::size() {
    return _used;
}
 
int iVector::push_back(int x) {
    if (_size == _used) {
        _data = (int *)realloc(_data, (_size * 2) * sizeof(int));
        _size <<=1;
    }
    _data[_used++] = x;
}

int* iVector::data() {
    return _data;
}

void iVector::set_size(int x) {
    _used = x;
}

int solve(int *v, int k, int n, int min, int max) {
    int sq = sqrt(n);
 
    iVector bucket[sq+1];
 
    /* First off we compute the minimum and the maximum element */
 
    int bucket_range;
 
    int index = 0;
    while (index < k) {
        if (min == max) {
            return v[0];
        }

        bucket_range = (max - min) / sq;
 
        for (int i = 0; i < n; ++ i) {
            bucket[ (v[i] - min) / bucket_range ].push_back(v[i]);
        }

        for (int i = 0; i <= sq; ++i) {
            int aux = (bucket[i].size()) ;
            if (index + aux < k) {
                index += aux;
            } else {
                n = bucket[i].size();
                memcpy(v ,bucket[i].data(), n * sizeof(int));
                min = min + i * bucket_range;
                max = min + bucket_range -1;
                break;
            }
        }
 
        sq = sqrt(n);
 
        for (int i = 0; i <=sq; ++i) {
            bucket[i].set_size(0);
        }
 
    }
 
    return -1;
 
}
 
int main() {
    int n, k, min = INT_MAX, max = 0;
 
    in>>n>>k;
 
    for (int i = 0; i < n; ++i) {
        in>>v[i];
        if (v[i] > max)
            max = v[i];
        if (v[i] < min)
            min = v[i];
    }    

    out<<solve(v, k, n, min, max)<< "\n";
 
    return 0;
}