Advertisement
alex0sunny

trash_indexes

Nov 15th, 2021 (edited)
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.69 KB | None | 0 0
  1. // Основная идея решения.
  2. //
  3. // Упорядочить элементы по возрастанию. Посчитать количество пар,
  4. // между которыми разность не больше чем, данная. Если количество
  5. // пар оказалось больше, чем k, то пробуем для меньшей разности,
  6. // если меньше, чем k, то делаем подсчёт для большей разности.
  7. // Используем двоичный поиск при этом.
  8. //
  9. // Подсчёт пар для заданной разности d основан на положении,
  10. // что если разность между крайними числами в промежутке равна d,
  11. // то и все пары в промежутке дают разность не превосходящую d.
  12. import java.io.*;
  13. import java.util.*;
  14. import java.util.stream.*;
  15.  
  16.  
  17. public class Main {
  18.  
  19.     // Функция выдаёт количество различных пар, которые
  20.     // могут дать d элементов.
  21.     static int countDiffs(int d) {
  22.         return (int)(d * (d - 1) * 0.5);
  23.     }
  24.  
  25.     // Функция выдаёт количество пар в листе a,
  26.     // дающих разности, не превосходящих целевую разность d.
  27.     static int countListDiffs(int[] a, int d)  {
  28.         int count, l, r, r_prev;
  29.         count = l = r = r_prev = 0;
  30.         while (r < a.length)  {
  31.             // Находим стартовую (левую) позицию для следующего полуинтервала,
  32.             // включающего пары, с разностью, не превышающей d.
  33.             // В первой итерации внешнего цикла ни одна итерация этого
  34.             // внутреннего цикла выполнена не будет.
  35.             while (a[r] - a[l] > d && l < r)  {
  36.                 l += 1;
  37.             }
  38.             // Сдвигаем правую границу до тех пор, пока полуинтервал
  39.             // [l; r) не будет включать максимально возможное количество
  40.             // пар, с разностью, не превосходящей d.
  41.             while (r < a.length && a[r] - a[l] <= d)  {
  42.                 r += 1;
  43.             }
  44.             // Любая из пар на полуинтервале [l; r) даёт разность,
  45.             // не превосходящую d.
  46.             count += countDiffs(r - l);
  47.             if (r_prev - l > 1) {
  48.                 // Если полуинтервал пересекается с предыдущим, то пары из
  49.                 // пересечения-полуинтервала [l; r_prev) учитываются
  50.                 // дважды при суммировании количеств. Необходимо вычесть
  51.                 // количество, которое даёт пересечение.
  52.                 count -= countDiffs(r_prev - l);
  53.             }
  54.             // Сохраняем предыдущее значение r, чтобы потом учесть
  55.             // возможное пересечение полуинтервалов.
  56.             r_prev = r;
  57.         }
  58.         return count;
  59.     }
  60.  
  61.     // Найти k-ю по величине разницу между элементами a.
  62.     static int getKth(int[] a, int k) {
  63.         Arrays.sort(a);
  64.         int lo = 0, hi = a[a.length-1], mid;
  65.         while (hi > lo) {
  66.             mid = (hi + lo) / 2;
  67.             if (countListDiffs(a, mid) < k) {
  68.                 // Если количество пар для разности mid меньше k,
  69.                 // то искомая разность будет больше mid и,
  70.                 // следовательно, нижняя граница lo будет больше mid.
  71.                 lo = mid + 1;
  72.             } else  {
  73.                 hi = mid;
  74.             }
  75.         }
  76.         return lo;
  77.     }
  78.  
  79.     public static void main(String[] args) throws IOException {
  80.         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  81.         reader.readLine();
  82.         String[] tokens = reader.readLine().split(" ");
  83.         int[] a = Stream.of(tokens)
  84.                     .mapToInt(token -> Integer.parseInt(token))
  85.                     .toArray();
  86.         int k = Integer.parseInt(reader.readLine());
  87.         int result = getKth(a, k);
  88.         System.out.println(result);
  89.     }
  90.  
  91. }
  92.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement