Мои попытки ускорить куб до O(1)

Revision ru18, by polosatic, 2023-02-07 09:54:01

Всем привет. Недавно мне в голову пришла следующая задача: Рассмотрим множество точек (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), используя эту идею

Tags математика, формула, задача

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en16 English polosatic 2023-02-07 09:55:02 82
ru18 Russian polosatic 2023-02-07 09:54:01 93
ru17 Russian polosatic 2023-02-07 05:28:56 129
en15 English polosatic 2023-02-07 05:27:56 131
en14 English polosatic 2023-02-07 05:25:34 35 Tiny change: 's together, then the' -> 's together and their product remains the same, then the'
ru16 Russian polosatic 2023-02-06 19:10:33 6
en13 English polosatic 2023-02-06 19:09:11 4916 Tiny change: ' < b`, let`s swap the' -> ' < b`, let's swap the'
ru15 Russian polosatic 2023-02-06 18:23:23 26 Мелкая правка: 'реугольник. Ясно, чт' -> 'реугольник второго типа. Ясно, чт'
ru14 Russian polosatic 2023-02-06 17:59:05 5245 Мелкая правка: 'видно.\n\n### Нако' -> 'видно.\n\n\n**UPD5:**\n### Нако'
en12 English polosatic 2023-02-05 15:32:48 368
ru13 Russian polosatic 2023-02-05 15:32:17 368
ru12 Russian polosatic 2023-02-05 14:43:45 5 Мелкая правка: 'm\n{\n ld x0 = 0, x' -> 'm\n{\n int x0 = 0, x'
en11 English polosatic 2023-02-05 14:43:27 5 Tiny change: 'm\n{\n ld x0 = 0, x' -> 'm\n{\n int x0 = 0, x'
en10 English polosatic 2023-02-05 14:39:44 22 Tiny change: '* (b - 1)`\n' -> '* (b - 1)`, but it was obvious.\n'
ru11 Russian polosatic 2023-02-05 14:38:59 53 Мелкая правка: 'е нашел :(\n' -> 'е нашел :(, кроме `x2 = b * (b - 1)`, что и так было очевидно.\n'
en9 English polosatic 2023-02-05 14:38:03 123 Tiny change: 'nything :(\n' -> 'nything :( except that `x2 = b * (b - 1)`\n'
ru10 Russian polosatic 2023-02-05 14:34:51 107
ru9 Russian polosatic 2023-02-05 14:31:11 1617 Мелкая правка: ' b ^ 2`.\n**UPD4:*' -> ' b ^ 2`.\n\n**UPD4:*'
en8 English polosatic 2023-02-05 14:29:36 1612
en7 English polosatic 2023-02-05 13:13:18 14 Tiny change: 'stand why interpolation doesn't w' -> 'stand why the formula doesn't w'
ru8 Russian polosatic 2023-02-05 13:12:54 71
en6 English polosatic 2023-02-05 13:11:58 81 Tiny change: 'tion doesn`t work wit' -> 'tion doesn't work wit'
en5 English polosatic 2023-02-05 13:08:43 2 Tiny change: ' use `ai >= b ^ 2`.\n' -> ' use `ai > b ^ 2`.\n'
ru7 Russian polosatic 2023-02-05 13:08:28 1 Мелкая правка: 'вать `ai >= b ^ 2`.\n' -> 'вать `ai > b ^ 2`.\n'
ru6 Russian polosatic 2023-02-05 12:46:30 1100 Мелкая правка: 'n\nТеперь у могу испо' -> 'n\nТеперь я могу испо'
en4 English polosatic 2023-02-05 12:41:12 1081 Tiny change: '}\n }\n return ans' -> '}\n }\n return ans'
ru5 Russian polosatic 2023-02-04 20:45:05 204
en3 English polosatic 2023-02-04 20:43:23 188 Tiny change: ', a > 1.\n**UPD:**' -> ', a > 1.\n\n**UPD:**'
ru4 Russian polosatic 2023-02-04 18:38:00 100
en2 English polosatic 2023-02-04 18:37:15 106
ru3 Russian polosatic 2023-02-04 18:36:35 4 Мелкая правка: ') = 2 * a * a - 4`, a >' -> ') = 2 * a ^ 2 - 4`, a >'
ru2 Russian polosatic 2023-02-04 18:24:17 107 Мелкая правка: 'for the nuber of rig' -> 'for the number of rig'
en1 English polosatic 2023-02-02 16:59:49 2162 Initial revision for English translation
ru1 Russian polosatic 2023-02-02 16:29:41 2268 Первая редакция (опубликовано)