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

Автор polosatic, история, 14 месяцев назад, По-русски

Всем привет. Недавно мне в голову пришла следующая задача: Рассмотрим множество точек (x, y) с целыми координатами таких, что 0 <= x < a и 0 <= y < b. Требуется найти количество остроугольных треугольников с вершинами в этих точках.

Попытки проинтерполировать

Ясно, что можно написать функцию f(a, b), которая будет искать ответ и работать при этом за (ab) ^ 3. Я предположил, что она ведет себя как многочлен от двух переменных степени не более 6. Я попытался её проинтерполировать, используя эту теорему. Но у меня ничего не получилось, так как при мономах степени больше 6 интерполяция давала ненулевой коэффициент. Не получилось также с тупоугольными и прямоугольными треугольниками.

code (для прямоугольных треугольников)

Данный код узнаёт коэффициент при мономе a ^ (C1 - 1) * b ^ (C2 - 1)

Что я хотел бы узнать:

  • решается ли эта задача быстрее, чем за куб
  • решается ли эта задача за O(1)
  • может, кто-нибудь знает задачи, где формула для ответа не очевидна и её можно подобрать этим методом?

UPD: найдена формула для количества прямоугольных треугольников с b = 2: f(a, 2) = 2 * a ^ 2 - 4, a > 1.

UPD2: большое спасибо bronze_coder за нахождение решения за O(1) для b = const: OEIS A189814.

Для интерполяции надо использовать ai > b ^ 2. EDIT: ai > (b - 1) ^ 2

UPD3: Наконец, я написал решение за O((ab) ^ 2).

Code

Теперь я могу использовать большие значения a и b для интерполяции.

Но всё равно кажется странным, что количество прямоугольных треугольников пропорционально (ab) ^ 2, а не (ab) ^ 3. Сейчас попробую понять, почему формула не работает для ai <= b ^ 2. EDIT: ai <= (b - 1) ^ 2

UPD4: Код, который находит формулу для f(a, b) при a > b ^ 2 и работает за O(b ^ 6):

Спойлер

Пытаясь найти закономерность в коэффициентах многочлена P, я обратился к OEIS, но ничего там не нашел :(, кроме x2 = b * (b - 1), что и так было очевидно.

UPD5:

Наконец-то нашёл формулу и решение за O(min(a, b) ^ 6)

Если a < b, то поменяем их местами. Теперь нужно решить за O(b ^ 6). Если a <= (b - 1) ^ 2 + 1, то запустим решение за O((ab) ^ 3) = O(b ^ 6). Теперь нужно разобраться с большими a.

Определения

Рассмотрим все прямоугольные треугольники и разделим их на 3 типа:

  1. треугольники, у которых нет вершин на прямой x = a - 1

  2. треугольники, у которых есть вершины на прямой x = a - 1 и две стороны параллельны осям координат

  3. остальные треугольники

Обозначим количество треугольников третьего типа за C(a) (какая-то функция от a).

Количество треугольников второго типа можно посчитать по формуле (a - 1) * b * (b - 1) / 2 * 4:

Доказательство

Из определения следует, что для вершин (x, y) треугольников первого типа выполняется 0 <= x < a - 1 и 0 <= y < b, то есть их количество равно f(a - 1, b), по определению функции f.

Итак, f(a, b) = f(a - 1, b) + (a - 1) * b * (b - 1) / 2 * 4 + C(a)

Теперь докажем, что C(a) при всех a > (b - 1) ^ 2 + 1 — константа.

Доказательство

C(a) — константа. Обозначим эту константу за c.

Итак, f(a, b) = f(a - 1, b) + (a - 1) * b * (b - 1) / 2 * 4 + c. Немного преобразований, и мы получаем формулу для f(a, b) через f((b - 1) ^ 2 + 1, b).

Преобразования
Реализация

К сожалению, c для разных b — разные, и я не смог найти между ними закономерность. Не помогли ни интерполяция, ни OEIS. Осталось несколько вещей, которые надо сделать:

  1. Выразить c через b, ведь c зависит только от b
  2. Решить задачу для a <= (b - 1) ^ 2 быстрее
  3. Решить задачу для остроугольных треугольников

Будет жёстко.

UPD6: Можно ускорить решение до O(b^5), используя эту идею

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

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

Auto comment: topic has been translated by polosatic (original revision, translated revision, compare)

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

The right triangle problem is OEIS A077435

EDIT: OEIS A189814 gives the answer for rectangles.

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

    Thank you! I was quite sure that problem with right triangles can be solved in O(a * b) But unfortunately, f(n, n) also is not a polynomial of one variable.

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

    OMG! I used too small ai for interpolation with constant b, so it didn't work. After using ai >= b ^ 2 everything works!

»
14 месяцев назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

Можно как минимум за квадрат решить, перебирая все пары направляющих векторов.

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

Автокомментарий: текст был обновлен пользователем polosatic (предыдущая версия, новая версия, сравнить).

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

Very nice

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

A not-implemented solution: let the triangle be tree vectors $$$a,b,c$$$.brute force $$$b-a$$$, and you will get $$$\dfrac{c-a}{|c-a|}$$$(which is rotate it for 90 deg(you can asumme ccw or cw))(In program, you can do it by a ). then you can brute force $$$c-a$$$ by $$$O(a + b)$$$. Then the problem is:

find how many triangles with vector $$$b-a=v$$$ and $$$c-a=w$$$?

which is trival.

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

    If I understand you correctly, I have already implemented this solution in UPD3 of this blog

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

      No. This solution is $$$O(ab(a+b))$$$.

      UPD3 is Brute force b-a and c-a, find if b-a ⊥ c-a and find how many triangles with vector b-a and c-a.

      But we can just brute force $$$|c-a|$$$(The length of c-a). the angle of $$$c-a$$$ is found by rotate $$$b-a$$$.

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

        Wow! Good idea! Thank you.

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

          why $$$O(a^2b^2(a+b))$$$ is $$$O(b^5)$$$? may $$$a \gg b^2$$$.

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

            The solution in UPD5 needs to calculate

            f((b - 1) ^ 2 + 1, b) and f((b - 1) ^ 2 + 2, b) to calculate f(a, b), it works in O(b ^ 6), but can be optimized to O(b ^ 5) using your method.