Блог пользователя tamir

Автор tamir, 11 лет назад, По-русски

Здравствуйте! Объясните решение задачи : Даны N различных чисел (1 <= N <= 2000,-1000000 <= a[i] <= 1000000 ). Нужно найти количество четверок чисел, сумма которых равна 0. Это задача со 2 тура 3-его этапа Республиканской олимпиады по информатике. Олимпиада уже завершена.

Спасибо!

  • Проголосовать: нравится
  • +7
  • Проголосовать: не нравится

»
11 лет назад, # |
Rev. 3   Проголосовать: нравится +6 Проголосовать: не нравится

Зафиксируем какие то 2 числа a[i] и a[j]. Пусть теперь мы хотим найти такие a[x] и a[y], что a[i] + a[j] + a[x] + a[y] == 0. Будем перебирать j в порядке убывания а i в порядке возрастания. Также будем хранить в массиве cnt[sum], количество пар различных чисел, дающих в сумме sum. Сначала перебираем j, потом i, после того, как мы зафиксировали 2 числа, нам нужно прибавить к ответу cnt[-(a[i] + a[j])]. После обработки всех таких i, i <= j, мы должны "добавить" наше число j к cnt, для чего мы перебираем все такие k, k > j, и делаем cnt[a[j] + a[k]]++. Код в первой правке.

  • »
    »
    11 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    А решение G можешь рассказать?

    • »
      »
      »
      11 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Занумеруем как — нибудь диагонали (как параллельные главной, так и побочной). Переберем центр (x, y) и размер k. Также, будем для каждого направления хранить (можно и не хранить, а считать напрямую, но так удобнее) клетку, в которую мы попадем, если будем идти в этом направлении рано k — 1 раз. Понятно, что если мы посчитали сумму в ромбе размерности k — 1, то чтобы получить сумму размерности k, нам достаточно добавить всего 4 диагонали, а именно диагонали, на которых лежат клетки (вверх, вправо), (вправо, вниз), (вниз, влево), (влево, вверх). Понятно, что не всегда в сумму входит вся диагональ, может только ее часть. Предпосчитаем для каждой диагонали префиксные суммы. Теперь чтобы получить нужные нам 4 диагонали, просто берем сумму за O(1) на соответствующей диагонали, храня для каждой клетки ее "индекс" в ней. Получается O(n * m * min(n, m))

»
11 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Важное уточнение. Количество четверок различных чисел?

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    ..Даны N различных чисел.

    • »
      »
      »
      11 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится

      И что? Где сказано, что в четверку не может входить какое-нибудь число дважды?

      • »
        »
        »
        »
        11 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Количество различных четверок чисел.В четверку не может входить какое-нибудь число дважды.