Хороші пари#9642

Хороші пари (Розбір)

Перепишемо умову a_i + a_j > b_i + b_j в такому вигляді:

a_i - b_i > – ( a_j - b_j)

Побудуємо масив різниць , в якому c_i = a_i - b_i. Відсортуємо його за зростанням. Нерівність a_i - b_i > - ( a_j - b_j) еквівалентно c_i > - c_j, або те ж саме що c_j > - c_i. Це нерівність також можна записати у вигляді:

c_i + c_j > 0

Тепер для кожного індексу i~(0 \le i \le n - 1) слід знайти мінімальний індекс , такий що c_j > - c_i. Для всіх індексів , які задовольняють умову j \le k \le n - 1, пари будуть хорошими. Однак, щоб не враховувати пари двічі, слід вибирати тільки ті з них, для яких k > i.

Приклад

Розглянемо наведений приклад. Відсортуємо масив c_i = a_i - b_i за зростанням.

Нехай i = 0. Шукаємо найменший індекс , такий що c_j > - c_0 = 3. Таким індексом буде j = 4. Відповідно, пари індексів і будуть хорошими.

Нехай i = 1. Шукаємо найменший індекс , такий що c_j > - c_1 = 1. Таким індексом буде j = 3. Відповідно, пари індексів (1, 3), (1, 4) і будуть хорошими.

Нехай i = 2. Шукаємо найменший індекс , такий що cj > - c_2 = 0. Таким індексом буде j = 3. Відповідно, пари індексів (2, 3), (2, 4) і будуть хорошими.

Нехай i = 3. Шукаємо найменший індекс , такий що c_j > - c_3 = -3. Таким індексом буде j = 1. Пара буде хорошою, якщо виконуються дві умови: k \ge j і k > i. В цьому випадку хорошими є пари індексів і . Пари і також будуть хорошими, але вони вже були враховані раніше при розгляді i = 1 (пара ) і i = 2 (пара ).

Нехай i = 4. Єдиною хорошою парою буде .

Всього є пар хороших індексів.

Реалізація алгоритму

Читаємо вхідні дані.

scanf("%d", &n);
a.resize(n); b.resize(n); 
for (i = 0; i < n; i++)
  scanf("%d", &a[i]);
for (i = 0; i < n; i++)
  scanf("%d", &b[i]);

Будуємо масив різниць , в якому c_i = a_i - b_i.

c.resize(n);
for (i = 0; i < n; i++)
  c[i] = a[i] - b[i];

Сортуємо масив за зростанням.

sort(c.begin(), c.end());

Кількість хороших пар індексів будемо підраховувати в змінній .

res = 0;

Перебираємо індекси .

for (i = 0; i < n; i++)
{

Для кожного індексу знаходимо мінімальний індекс , такий що c_{pos} > - c_i. При цьому має виконуватися умова pos \ge i + 1.

  pos = lower_bound(c.begin() + i + 1, c.end(),-c[i] + 1) - c.begin();

Хорошими будуть всі пари індексів , для яких pos \le k \le n - 1. Кількість таких значень дорівнює (n - 1) - pos + 1 = n - pos.

  res += n - pos;
}

Виводимо відповідь.

printf("%lld\n", res);