Yaxşı cütlər#9642

Yaxşı cütlər (Həll təhlili)

a_i + a_j > b_i + b_j şərtini aşağıdakı kimi yenidən yazaq:

a_i - b_i > – ( a_j - b_j)

fərqlərdən ibarət bir massiv quraq, burada c_i = a_i - b_i. Onu artan sıra ilə sıralayaq. a_i - b_i > - ( a_j - b_j) qeyri-bərabərliyi c_i > - c_j ya eyni olan c_j > - c_i bərabərliyinə ekvivalentdir. Bu qeyri-bərabərliyi həmçinin aşağıdakı formada yaza bilərik:

c_i + c_j > 0

İndi hər bir indeks üçün i~(0 \le i \le n - 1) minimal indeksini tapmalıyıq ki, c_j > - c_i olsun. Şərtə uyğun olan bütün j \le k \le n - 1 indeksləri üçün cütləri yaxşı olacaq. Lakin, cütləri iki dəfə hesaba almamaq üçün yalnız k > i olanları seçməliyik.

Nümunə

Göstərilən nümunəni nəzərdən keçirək. c_i = a_i - b_i massivini artan sıra ilə sıralayaq.

t_i = 0 edək. Minimal indeksini axtarırıq ki, c_j > - c_0 = 3 olsun. Bu indeks j = 4 olacaq. Beləliklə, və indeks cütləri yaxşı olacaq.

i = 1 edək. Minimal indeksini axtarırıq ki, c_j > - c_1 = 1 olsun. Bu indeks j = 3 olacaq. Beləliklə, (1, 3), (1, 4) və indeks cütləri yaxşı olacaq.

i = 2 edək. j = 3 olan minimal indeksini axtarırıq ki, c_j > - c_2 = 0. Beləliklə, (2, 3), (2, 4) və indeks cütləri yaxşı olacaq.

i = 3 edək. c_j > - c_3 = -3 olan minimal indeksini axtarırıq. Bu indeks j = 1 olacaq. cütü yaxşı olacaq, əgər iki şərt təmini olunsa: k \ge j və k > i. Bu vəziyyətdə, və indeks cütləri yaxşı olacaq. (3, 1) və (3, 2) cütləri də yaxşıdır, lakin onlar artıq i = 1~((1, 3) cütü) və i = 2~((2, 3) cütü) hallarında nəzərə alınmışdılar.

i = 4 edək. Yalnız yaxşı cüt olacaq.

Ümumilikdə yaxşı indeks cütü var.

Alqoritmin realizasiyası

Giriş məlumatları oxumaq.

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]);

fərqlərdən ibarət bir massiv quraq, burada c_i = a_i - b_i.

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

massivini artan sıra ilə düzün.

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

Yaxşı indeks cütlərinin sayını dəyişənində toplayacağıq.

res = 0;

İndeksləri üzrə dolaşırıq.

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

Hər bir indeks üçün , minimal indeksini tapaq ki, c_{pos} > - c_i olsun. Buradaxıçin pos \ge i + 1 şərti də yerinə yetirilməlidir.

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

Yaxşı olan bütün indeks cütləri, pos \le k \le n - 1 üçün olacaq. üçün olan belə dəyərlərin sayı (n - 1) - pos + 1 = n - pos.

  res += n - pos;
}

Cavabı çap edək.

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