Cod sursa(job #1007703)

Utilizator vlad.doruIon Vlad-Doru vlad.doru Data 9 octombrie 2013 16:54:31
Problema Statistici de ordine Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <climits>
#include <vector>
#include <algorithm>

using namespace std;

ifstream in("sdo.in");
ofstream out("sdo.out");

const int N = 3000000;

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;

}

int solve(int *v, int k, int n) {
	int sq = sqrt(n);

	vector<int> bucket[sq+1];

	/* First off we compute the minimum and the maximum element */

	int min = INT_MAX, max = 0;

	int bucket_range;

	int index = 0;

	// while (index < k) {
	// 	memset(frecv, 0, sq + 1);
	// 	for (int i = 0; i < n; ++i) {
	// 		frecv[ (i - min) / bucket_range ]++;
	// 	}

	// 	int ruled_out = 0;
	// 	for (int i = 0; i <= sq; ++i ) {
	// 		ruled_out += frecv[i];
	// 		if (ruled_out > k) {
	// 			index += (ruled_out - frecv[i]);
	// 			n = frecv[i];
	// 		}
	// 	}

	// 	sq = sqrt(n);

	// }

	while (index < k) {

		min = INT_MAX, max = 0;

		for (int i = 0; i + 1 < n; i+=2 ) {
			if (v[i] < v[i+1]) {
				min = min > v[i]   ? v[i]   : min;
				max = max < v[i+1] ? v[i+1] : max;
			} else {
				min = min > v[i+1] ? v[i+1] : min;
				max = max < v[i]   ? v[i]   : max;
			}
		}

		min = min > v[n-1] ? v[n-1] : min ;
		max = max < v[n-1] ? v[n-1] : max ;

		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]);
		}

		int ruled_out = 0;

		for (int i = 0; i <= sq; ++i) {
			int aux = (bucket[i].size()) ;
			if (index + bucket[i].size() < k) {
				index += bucket[i].size();
			} else {
				n = bucket[i].size();
				for ( int j = 0; j< bucket[i].size() ; ++j) {
					v[j] = bucket[i][j];
				}
				/* memcpy(v ,bucket[i].data(), n); */
				break;
			}
		}

		sq = sqrt(n);

		for (int i = 0; i <=sq; ++i) {
			bucket[i].clear();
		}

	}

	return bucket_range;

}

int main() {
	int n, k;

	in>>n>>k;

	for (int i = 0; i < n; ++i) {
		in>>v[i];
	}

	out<<solve(v, k, n)<< "\n";

	return 0;
}