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