Cod sursa(job #1007718)

Utilizator vlad.doruIon Vlad-Doru vlad.doru Data 9 octombrie 2013 17:20:56
Problema Statistici de ordine Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 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);

	int *frecv = new int[sq+1];
	//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;

	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 ;

	// 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();
	// 	}

	// }

	memset(frecv, 0, sq+1);


	while (index < k) {

		if (min == max) {
			return v[0];
		}

		bucket_range = (max - min) / sq;

		for (int i = 0; i < n; ++ i) {
			frecv[ (v[i] - min) / bucket_range ]++;
		}

		for (int i = 0; i <= sq; ++i) {
			if (index + frecv[i] < k) {
				index += frecv[i];
			} else {
				min = min + i * bucket_range;
				max = min + bucket_range -1;
				int aux = 0;
				for ( int j = 0; j < n ; ++j) {
					if (v[j] >= min && v[j] <= max ){
						v[aux++] = v[j];
					}
				}
				n = frecv[i];
				break;
			}
		}

		sq = sqrt(n);

		memset(frecv, 0, (sq+1) * sizeof(int));

	}

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