Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- using namespace std;
- int n;
- void print(int* A, int L, int midL, int midR, int R)
- {
- for (int i = 0; i < n; i++)
- {
- if (i == L)
- printf("[");
- if (i - 1 == midL)
- printf("(");
- printf("%d", A[i]);
- if (i + 1 == midR)
- printf(")");
- if (i == R)
- printf("]");
- printf(" ");
- }
- printf("\n");
- }
- void partition(int* A, const int &MED, int L, int R, int &midL, int &midR)
- {
- int mid = L;
- while (mid <= R)
- {
- int tmp;
- if (A[mid] < MED)
- {
- tmp = A[L];
- A[L] = A[mid];
- A[mid] = tmp;
- L++;
- mid++;
- }
- else if (A[mid] == MED)
- {
- mid++;
- }
- else
- {
- tmp = A[R];
- A[R] = A[mid];
- A[mid] = tmp;
- R--;
- }
- }
- midL = L - 1;
- midR = mid;
- }
- void insertSort(int* A, const int &L, const int &R)
- {
- if (L == R)
- return;
- for (int i = L + 1; i <= R; i++)
- {
- int key = A[i];
- int j = i - 1;
- while (j >= 0 && A[j] > key)
- {
- A[j + 1] = A[j];
- j = j - 1;
- }
- A[j + 1] = key;
- }
- }
- int max(const int &a, const int &b)
- {
- return (a<b) ? b : a;
- }
- int min(const int &a, const int &b)
- {
- return (a>b) ? b : a;
- }
- // https://stackoverflow.com/questions/480960/code-to-calculate-median-of-five-in-c-sharp
- int med3(int &a, int &b, int &c)
- {
- return max(min(a, b), min(c, max(a, b)));
- }
- int med5(int &a, int &b, int &c, int &d, int &e)
- {
- int f = max(min(a, b), min(c, d));
- int g = min(max(a, b), max(c, d));
- return med3(e, f, g);
- }
- int smallMedian(int* A, const int &L, const int &R)
- {
- if (L - R != 5)
- {
- insertSort(A, L, R);
- return A[L + (R - L) / 2];
- }
- else
- {
- return med5(A[L], A[L + 1], A[L + 2], A[L + 3], A[L + 4]);
- }
- }
- int medianOfMedians(int* A, int* medians, int L, int R)
- {
- if (R - L <= 10)
- {
- return smallMedian(A, L, R);
- }
- int medSize = (R - L + 4) / 5;
- int i = 0;
- int j = 0;
- for (; i < medSize - 1; i++, j += 5)
- medians[i] = smallMedian(A, L + j, L + j + 4);
- medians[i] = smallMedian(A, L + j, R);
- return medianOfMedians(medians, medians, 0, medSize - 1);
- }
- int kth(int* A, int* medians, int k, int L, int R)
- {
- if (R - L < 10)
- {
- insertSort(A, L, R);
- return A[k];
- }
- int MED = medianOfMedians(A, medians, L, R);
- int midL;
- int midR;
- //printf("%d %d\n", MED, k);
- partition(A, MED, L, R, midL, midR);
- //print(A, L, midL, midR, R);
- if (midL < k && k < midR)
- {
- //printf("{0}");
- return A[midL + 1];
- }
- else
- {
- if (k <= midL)
- {
- //printf("{-1}");
- return kth(A, medians, k, L, midL);
- }
- else
- {
- //printf("{1}");
- return kth(A, medians, k, midR, R);
- }
- }
- }
- int main()
- {
- int z, k;
- scanf("%d", &z);
- while (z--)
- {
- scanf("%d %d", &n, &k);
- k--;
- int* A = new int[n];
- int* medians = new int[n / 5 + 1];
- for (int i = 0; i < n; i++)
- scanf("%d", &A[i]);
- printf("%d\n", kth(A, medians, k, 0, n - 1));
- //printf("\n");
- delete[] A;
- delete[] medians;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement