GithubHelp home page GithubHelp logo

algo3.teor's Introduction

Algo3.teor

Задача 1

Условие

Найти в графе количество треугольников за O(E^1.5).

Решение

Будем проходиться поиском в глубину по следующему алгоритму:

  1. Для текущей вершины рассматриваем всех еще не посещенных соседей.
  2. Запускаем поиск в глубину длины два, и если вершина, в которую мы пришли на глубине два, является текущей вершиной, то прибавляем один треугольник.
  3. Помечаем текущую вершину как посещенную.
  4. Запускаемся из другой, еще не посещенной, вершины.

Таким образом, алгоритм проходит не более |V| циклом (из каждой вершины в худшем случае), причем каждое ребро в алгоритме используется ровно один раз, то есть максимальная сложность внутри цикла O(|E|). Тогда получаем сложность O(|V||E|).

Разобъем вершины на две части: в первой будут вершины степени больше, чем √E, а во второй остальные. По алгоритму выше переберем все находящиеся в первой части вершины x. Таких вершин будет не более 2√E. Тогда мы найдем все треугольники, в которых хотя бы одна из вершин степени больше √E. Сложность O(E√E).

Далее найдем все треугольники, все вершины которых имеют меньшую степень. Для этого перебираем ребра (x, y) и перебираем соседей вершины меньшей степени (которые еще проверяем на степень меньше √E). Среди этих соседей ищем ребро в другую вершину. Тогда получаем сложность Сложность E*∑min(deg(x), deg(y)), (x,y) - ребра. Тогда получаем сложность O(E√E).

Следовательно, все треугольники находим за O(E√E).

Задача 2

Условие

Ориентировать неор граф так, чтобы он стал сильносвязным за O(V+E), или сказать, что это невозможно.

Решение

Очевидно, что нельзя ориентировать требуемым способом граф, содержащий мосты (так как будет путь только в одну сторону), либо вовсе не являющийся связным. Тогда будем рассматривать графы без мостов, они будут реберно-двусвязными. Через обход в глубину из какой-то вершины X находим минимальное остовное дерево (тут возникает O(V + E)). Тогда достаточно будет ориентировать ребра остовного дерева по направлению к X, а остальные по направлению от X (сложность O(E)). Тогда получаем сильносвязный граф, так как мы сможем по ребрам остовного дерева в одном направлении, а по остальным в обратном, то есть из любой вершины можно будет добраться в любую другую.

Задача 3

Условие

Разбить все ребра неорграфа на минимальное число путей за 𝒪(𝑉 + 𝐸).

Решение

Заметим, что эта задача эквивалентна задаче о минимальном дополнении каждой компоненты связности графа до Эйлерова цикла, так как найдя Эйлеров цикл и удалив из него добавленные ребра, мы получим распавшийся на несколько новых путь. Их будет столько же, сколько ребер мы добавляли. Тогда дополним каждую компоненту связности до Эйлерова цикла, любым образом паросочетая вершины нечетной степени. Тогда получаем требуемую асимптотику O(V + E).

Задача 4

Условие

Для каждой пары вершин в графе найти 𝑤[𝑎, 𝑏] – такой минимальный вес, что из 𝑎 в 𝑏 есть путь по рёбрам веса <= 𝑤[𝑎, 𝑏]. O(V^2)

Решение

Построим минимальное остовное дерево через алгоритм Прима (асимптотика O(V^2) в случае плотного графа). Так как каждая вершина будет добавлена только со своим минимальным ребром (которое связывает ее с текущим MST). Тогда в полученном остовном дереве мы можем запустить поиск в ширину из каждой вершины. Тогда сложность этого будет O(V^2 + VE). Но ведь у нас дерево, где |E| <= |V|, тогда общая сложность алгоритма будет O(V^2).

Задача 5

Условие

Дана система из 𝑚 неравенств на 𝑛 переменных вида 𝑥 𝑖 − 𝑥 𝑗 ≤ 𝛿 𝑖𝑗 . Найти решение системы или сказать, что его не существует, за 𝒪(𝑛𝑚).

Решение

Задача 6

Условие

Найти в графе цикл минимального среднего веса V, E <= 2000, |w_i| <= 10**9.

Решение

Добавим к графу фиктивную вершину S и проведем из нее ребра во все остальные вершины. Далее запустим алгоритм Форда-Белмана, построив с его помощью матрицу dist[v][l] - длина минимального пути из S в V, содержащего ровно L ребер. Тогда, чтобы найти цикл минимального среднего веса, нужно посчитать min(v) max(k) (dist[v][N] - dist[v][k]) \ (N - k). Достаточно будет доказать это правило для оптимальной длины равной нулю, так как для других оптимальных длин можно просто отнять эту величину от всех ребер и получить снова случай с нулевой длиной.

Чтобы найти цикл после построения матрицы dist[v][k], запомним, при каких v и k достигается оптимальное значение, и, используя dist[v][n], будем идти по указателям к предкам. Когда достигли исходной вершины, цикл готов. Тогда итоговая сложность алгоритма O(VE).

Задача 7

Условие

Дан массив чисел. За 𝒪(log 𝑛) в online обрабатывать запросы: • посчитать сумму кубов чисел на отрезке [𝐿, 𝑅]; • прибавить 𝑥 ко всем числам на отрезке [𝐿, 𝑅]; • получить значение 𝑖-го числа.

Решение

Будем реализовывать дерево отрезков для суммы, но с добавлением в узлы еще двух полей - суммы кубов и суммы квадратов на отрезке. Зачем же нам нужны данные поля? При увеличении всех чисел на отрезке на b сумма кубов на данном отрезке увеличится и будет равна ∑(a_i + b)^3 = ∑(a_i)^3 + 3b∑(a_i)^2 + 3b^2∑a_i + b^3∑1. Аналогично раскрываем формулу для обновления суммы квадратов на отрезке и получаем ∑(a_i + b)^2 = ∑(a_i)^2 + 2b∑a_i + b^2∑1. Также будем хранить promise, который будем в случае необходимости пушить в детей, как и в классической реализации дерева отрезков для суммы. Тогда при обновлении отрезка будем сначала обновлять сумму кубов (так как она использует сумму квадратов и простую сумму), затем квадратов и наконец простую сумму. Тогда алгоритм работает за O(logN), как и классического дерево отрезков для суммы.

Задача 8

Условие

Есть массив из нулей и единиц. В online за 𝒪(log 𝑛) отвечать на запросы: поменять элемент; найти ближайший слева/справа ноль к позиции 𝑖.

Решение

Построим дерево отрезков, где узлами будут пары значений - левая и правая крайние позиции нулей на отрезке. В случае, если на отрезке нет нулей, оба значения будут равны -1. Тогда чтобы поменять элемент, нам нужно обновить узел-лист и подниматься по родителям. Тогда обновляем значения родителей до тех пор, пока оно изменяет хотя бы одно из своих значений. Запрос на ближайший ноль обрабатываем следующим образом:

  1. Если мы корень, то таких нулей нет.
  2. Поднимаемся в родителя и смотрим его второго сына: если мы пришли из левого (правого) сына, то смотрим на значение крайнего левого (крайнего правого) нуля на данном отрезке. Если такой есть, то мы нашли положение крайнего правого (левого) нуля. Если родитель - корень, и крайний левый (правый) элемент еще не найден, то он не существует.
  3. Повторяем П.2 до тех пор, пока не дойдем до корня.

Так как используется структура дерева отрезков, сложность операций будет O(logN).

Задача 9

Условие

Запросы: сумма на отрезке, прибавить 𝑎𝑖 + 𝑏 к 𝑖-у элементу отрезка [𝐿, 𝑅]. для всех 𝑖. То есть, сделать array[L + i] += a*i + b. O(log n).

Решение

algo3.teor's People

Contributors

az0t24 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.