Advertisement
smatskevich

KStatOptimized

Oct 28th, 2017
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.92 KB | None | 0 0
  1. #include <assert.h>
  2. #include <iostream>
  3. #include <vector>
  4. using std::vector;
  5.  
  6. // Разбиение массива по опорному элементу.
  7. // Возвращает индекс, на котором будет расположен опорный элемент после разбиения.
  8. // Опорный элементы выбирается неэффективно - в конце массива.
  9. int Partition( vector<int>& data, int left, int right )
  10. {
  11.     assert( left < right );
  12.     const int& pivot = data[right - 1];
  13.     int i = left;
  14.     int j = right - 2;
  15.     while( i <= j ) {
  16.         // Двигаем i вправо до элемента больше либо равного pivot.
  17.         for( ; data[i] < pivot; ++i ) {}
  18.         // Двигаем j влево до элемента меньше либо равного pivot.
  19.         // Так добиваемся того, что в случае большого количества элементов равных pivot,
  20.         // они расположатся примерно равномерно слева и справа.
  21.         for( ; j >= left && pivot < data[j]; --j ) {}
  22.         if( i < j ) {
  23.             std::swap( data[i], data[j] );
  24.             ++i;
  25.             --j;
  26.         }
  27.     }
  28.     std::swap( data[i], data[right - 1] );
  29.     return i;
  30. }
  31.  
  32. // Возвращает k-ую порядковую статистику. k считается от 0.
  33. int KStat( vector<int>& data, int k )
  34. {
  35.     assert( k >= 0 && k < static_cast<int>( data.size() ) );
  36.     int left = 0;
  37.     int right = data.size(); // Не включаем right.
  38.     while( true ) {
  39.         int pivotPos = Partition( data, left, right );
  40.         if( pivotPos == k ) {
  41.             return data[k];
  42.         }
  43.         if( pivotPos > k ) {
  44.             right = pivotPos;
  45.         } else {
  46.             left = pivotPos + 1;
  47.         }
  48.     }
  49. }
  50.  
  51. int main()
  52. {
  53.     int n = 0;
  54.     int k = 0;
  55.     std::cin >> n >> k;
  56.     vector<int> data( n );
  57.     for( int i = 0; i < n; ++i ) {
  58.         std::cin >> data[i];
  59.     }
  60.     std::cout << KStat( data, k );
  61.     return 0;
  62. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement