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

Автор teraqqq, история, 9 часов назад, По-русски

В этом году проходил BSUIR Open XIV, мне было очень приятно съездить в Минск и на само соревнование. Но еще больше мне понравилась задачу, которую я туда предложил. В целом я не видел эту идею раньше, но она кажется достаточно простой, чтобы появиться раньше на каких-нибудь соревнованиях. Так что если вы знаете, где раньше встречалась это идея, то поделитесь, пожалуйста.

Задача. (*BSUIR OPEN XIV*) Дано клеточное поле $$$100 \times 100$$$, в котором между некоторыми клетками проведены стены, также стены проведены по границе поля. Луч запускается из центра клетки $$$(r,c)$$$ в направлении $$$(x,y)$$$. Требуется определить, в какой клетке он окажется, пройдя расстояние $$$\sqrt{x^2+y^2}$$$, если луч отражается от стен.

Решение задачки

Взглянем на вектор $$$(x,y)$$$ и посмотрим, в каком порядке он пересекает вертикальные и горизонтальные линии сетки. В точке $$$(0,0)$$$ пересечение с линиями сетки учитывать не будем, но будем учитывать пересечения в точке $$$(x,y)$$$, причем по формальным причинам мы будем считать, что сначала происходит пересечение с вертикальной прямой.

Последовательность пересечений можно записать в виде строки:

  • $$$R$$$ обозначает пересечение вертикальной линии сетки (перемещение на клетку вправо),
  • $$$U$$$ обозначает пересечение горизонтальной линии сетки.

Тогда каждому вектору $$$(x,y)$$$ можно сопоставить строку $$$s(x, y)$$$, содержащую последовательность этих пересечений. Например,

$$$ s(4,3) = \texttt{RURURRU}. $$$

Предположим, что $$$x \ge y$$$. Это означает, что вектор «пологий», и перед каждым пересечением горизонтальной линии происходит пересечение вертикальной. А именно, перед $$$k$$$-м символом U стоит

$$$ \left\lfloor \frac{x}{y} \cdot k \right\rfloor - \left\lfloor \frac{x}{y} \cdot (k-1) \right\rfloor $$$

подряд идущих символов R.

Таким образом, перед каждым символом U стоит блок, состоящий как минимум из $$$\left\lfloor x/y \right\rfloor$$$ символов R; эти блоки вместе с символами U можно сжать в один символ. Например,

$$$ s(4,3) = \texttt{RURURRU} = (\texttt{RU})(\texttt{RU})\texttt{R}(\texttt{RU}) \to s(1,3)=\texttt{UURU}. $$$

Таким образом, можно предположить, что если $$$s(x, y, R, U)$$$ — это строка $$$s(x,y)$$$, где на месте символов R и U стоят строки $$$R$$$ и $$$U$$$, то верно равенство:

$$$ s(x,y,R,U)= \begin{cases} s(x-y\lfloor x/y\rfloor,\ y,\ R,\ R^{\lfloor x/y\rfloor}U), & x\ge y, \\\\ s(x,\ y-x\lfloor (y-1)/x\rfloor,\ U^{\lfloor (y-1)/x\rfloor}R,\ U), & x \lt y. \end{cases} $$$

Ясно, что это правда. Например, в случае $$$x \ge y$$$ достаточно убедиться в том, что перед $$$k$$$-м символом $$$U$$$ после подстановки сохраняется количество подряд идущих букв R:

$$$ q = \left\lfloor \frac{x}{y} \right\rfloor: \qquad q + \left\lfloor \frac{x-qy}{y}\cdot k \right\rfloor - \left\lfloor \frac{x-qy}{y}\cdot (k-1) \right\rfloor $$$
$$$ = q + \left\lfloor \frac{x}{y}\cdot k - qk \right\rfloor - \left\lfloor \frac{x}{y}\cdot (k-1) - q(k-1) \right\rfloor $$$
$$$ = \left\lfloor \frac{x}{y}\cdot k \right\rfloor - \left\lfloor \frac{x}{y}\cdot (k-1) \right\rfloor. $$$

Таким образом, строку $$$s(x,y)$$$ можно вычислять с помощью алгоритма Евклида. Разумеется, в общем случае нам нужна не строка, а какая-то более полезная информация. Символы R и U могут принадлежать произвольному моноиду, для которого можно эффективно вычислять следующие операции:

  • произведение элементов;
  • возведение элемента в степень.

Например, в качестве моноида могут выступать перестановки, матрицы или любые другие объекты, которые можно поддерживать в дереве отрезков. В частности, в подстроке $$$s(x,y)$$$ можно поддерживать количество подпоследовательностей UR, что соответствует вычислению значения floor_sum (только в таком случае надо аккуратно разобраться с приоритетами символов R и U).

Обобщённо алгоритм трекинга вектора может быть реализован следующим образом:

Скачать код без регистрации и СМС
Решение задачи

Другие обобщения

В ходе алгоритма можно строить не композицию моноидов $$$R$$$ и $$$U$$$, а последовательность неполных частных вместе со всеми промежуточными вычислениями. Например, при входных данных $$$(x,y)$$$ таблица вычислений будет выглядеть следующим образом. Напомним, что

$$$ q = \max\left\{\left\lfloor \frac{x}{y}\right\rfloor,\ \left\lfloor \frac{y-1}{x}\right\rfloor\right\}. $$$
Шаг Вычисленное значение $$$q$$$ $$$x$$$ $$$y$$$
1 RU 1 4 3
2 RURUR 2 1 3
3 RURURRU 1 1 1

Работая со всеми промежуточными вычислениями, можно дополнительно обрабатывать следующие сценарии:

  • композицию моноидов $$$R$$$ и $$$U$$$ на любом подотрезке $$$(l,r)$$$ строки $$$s(x,y)$$$.

Так, если запускать вектор не из точки $$$(0,0)$$$, а из произвольной точки $$$(\alpha, \beta)$$$, то может получиться строка $$$s(x,y,\alpha,\beta)$$$, отличная от $$$s(x,y)$$$. Но также ясно, что строка $$$s(x,y,\alpha,\beta)$$$ получается циклическим сдвигом строки $$$s(x,y)$$$.

Чтобы понять, что именно это будет за циклический сдвиг, вспомним, что строку $$$s$$$ можно представить в виде объединения блоков вида R...RU, где количество букв R перед $$$k$$$-й буквой U вычисляется по формуле:

$$$ \left\lfloor \frac{x}{y}\cdot k \right\rfloor - \left\lfloor \frac{x}{y}\cdot (k-1) \right\rfloor = \frac{x}{y}\cdot k - \frac{xk \bmod y}{y} + \frac{x(k-1) \bmod y}{y}. $$$

Таким образом, если вектор запускается из произвольной точки $$$(\alpha/y, 0)$$$, то длина $$$k$$$-го блока будет вычисляться по похожей формуле:

$$$ \left\lfloor \frac{x}{y}\cdot k + \frac{\alpha}{y} \right\rfloor - \left\lfloor \frac{x}{y}\cdot (k-1) + \frac{\alpha}{y} \right\rfloor = \frac{x}{y}\cdot k - \frac{(xk + \alpha) \bmod y}{y} + \frac{(x(k-1) + \alpha) \bmod y}{y}. $$$

В случае взаимной простоты $$$x$$$ и $$$y$$$ можно сделать замену

$$$ \alpha = k_0 x \pmod y. $$$

И тогда число $$$k_0$$$ и будет искомым циклическим сдвигом.

Таким образом, предлагаемый алгоритм является универсальным (и, вероятно, не лучшим по константе времени исполнения) способом для решения многих задач-обобщений floor_sum. В частности,

$$$ f(l, r, p, q, a, b, c) = \sum_{x=l}^r \left\lfloor \frac{a+bx}{c} \right\rfloor^p x^q $$$

можно вычислить за время

$$$ O(\log C \cdot pq(p+q)) $$$

в общем случае, что достаточно приятно.

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

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

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

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

Auto comment: topic has been updated by teraqqq (previous revision, new revision, compare).