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

Автор SpamBot, история, 2 года назад, По-русски

Дана перестановка длинны n ≤ 10^5. Каждый её элемент раскрашен в один из n цветов. Необходимо для каждого элемента i найти количество инверсий одного с ним цвета. Ожидаемая сложность n log(n).

Кроме очевидного "для каждого цвета взять дерево отрезков и посчитать инверсии" мне в голову ничего не приходит. Что ещё можно попробовать?

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

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

Что имеется ввиду под "инверсии одного с ним цвета"?

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

    Есть перестановка p и массив c ( c[i] <= n ). Найти количество пар p[i], p[j], что:

    1. p[i] > p[j]

    2. i < j

    3. c[i] = c[j]

    Если я правильно понял, то как-то так.

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

А почему не подходит просто, как было написано, "для каждого цвета взять дерево отрезков и посчитать инверсии"? Перебираем все цвета, потом смотрим элементы только с этим цветом и считаем инверсии, потом чистим структуру, с помощью которой мы это считали. Важно, чтобы очистка происходила за $$$O(cnt_{col})$$$, где $$$cnt_{col}$$$ — количество элементов цвета $$$col$$$. Вот мы и получили $$$O(NlogN)$$$.

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

    Единственный известный мне способ подсчёта инверсий при помощи дерева следующий: tab[i] — количество инверсий для i-того элемента.

    Реализация дерева (Фенвика)

    Задаем size=n+1, далее идём по массиву в порядке возрастания индексов: tab[i]=t.sum(p[i]+1, n); t.upd(p[i]);

    Если сначала отсортировать пары (p[i], c[i]) (stable_sort) по цвету, а затем находить инверсии для каждого цвета по-отдельности, то обнулять val дерева придётся O(n) раз, итого O(n*n).

    Если же для каждого цвета выделить своё дерево, то тогда по памяти выходит O(n*n).

    Или инверсии можно находить иначе?

    А что насчёт задачи нахождения общего количества одноцветных инверсий? Может она проще решается?

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

      Можно заметить, что мы делаем для каждого цвета $$$O(cnt_{col})$$$ вызовов функции $$$t.upd()$$$, а также несложно понять, что $$$\sum_{col \in colors}{cnt_{col}} = N$$$, где $$$cnt_{col}$$$ — количество элементов с цветом $$$col$$$. То есть, мы для каждого цвета сначала можем проходиться и добавлять в Фенвик эти элементы, а потом снова пройтись по этим же элементам и удалих их из Фенвика. Итого $$$O(NlogN)$$$, а не $$$O(N^2)$$$