Есть массив отсчётов, последовательность вещественных чисел
![$x_0, x_1, \dots , x_n$ $x_0, x_1, \dots , x_n$](https://dxdy-01.korotkov.co.uk/f/c/4/3/c4329ce8888412add9a6a49be557a63182.png)
, ему соответствует массив времён
![$t_0, t_1, \dots , t_n$ $t_0, t_1, \dots , t_n$](https://dxdy-03.korotkov.co.uk/f/a/4/e/a4e463e93de660a1b49a6a499bdf67ec82.png)
, нужно эти отсчёты как-то сгладить. Один из способов состоит в следующем: нарисуем пары точек
![$(t_i, x_i)$ $(t_i, x_i)$](https://dxdy-04.korotkov.co.uk/f/7/a/0/7a0d8a27278d4c5016d9474bef753b6b82.png)
на координатной плоскости
![$(t, x)$ $(t, x)$](https://dxdy-03.korotkov.co.uk/f/a/f/4/af41945d59e55fa5f7f0852c18eb186582.png)
, рассмотрим их как как точки на графике некоторой (неизвестной нам) функции
![$x = x(t)$ $x = x(t)$](https://dxdy-03.korotkov.co.uk/f/2/a/c/2ac2fb0261fe562f188ba08f6bf3f5cb82.png)
, соединим эти точки последовательно ломаной (то есть просто берётся кусочно линейная интерполяция). за пределы отрезка
![$[t_0, t_n]$ $[t_0, t_n]$](https://dxdy-02.korotkov.co.uk/f/9/2/9/929b4591b7a4f6b8c3e0820cd2bd4c1082.png)
продолжим функцию константами: влево константой
![$x_0$ $x_0$](https://dxdy-03.korotkov.co.uk/f/e/7/1/e714a3139958da04b41e3e607a54445582.png)
, вправо
![$x_n$ $x_n$](https://dxdy-02.korotkov.co.uk/f/d/7/0/d7084ce258ffe96f77e4f3647b250bbf82.png)
. Получившуюся кусочно-линейную функцию обозначим через
![$f(t)$ $f(t)$](https://dxdy-03.korotkov.co.uk/f/2/7/0/27099e26220f898359382d05f75b941c82.png)
. Получившийся график не очень красив, хочется его сгладить, для этого зададимся некоторым числом
![$\delta$ $\delta$](https://dxdy-04.korotkov.co.uk/f/3/8/f/38f1e2a089e53d5c990a82f28494895382.png)
, и определим функцию:
![$$
F(t) = \int\limits_{t - \delta}^{t + \delta} f(t) dt
$$ $$
F(t) = \int\limits_{t - \delta}^{t + \delta} f(t) dt
$$](https://dxdy-02.korotkov.co.uk/f/d/6/9/d69a554be0057a47501992c13532744982.png)
Задача состоит в том, чтобы (эффективно) посчитать массив значений
![$F(t_0), F(t_1), \dots , F(t_n)$ $F(t_0), F(t_1), \dots , F(t_n)$](https://dxdy-03.korotkov.co.uk/f/e/a/f/eaf9e4e768ea036682df498c2d8f398782.png)
.
Наивный алгоритм имеет асимптотику
![$O(n^2)$ $O(n^2)$](https://dxdy-04.korotkov.co.uk/f/3/9/8/3987120c67ed5a9162aa9841b531c3a982.png)
, если немного улучшить его бинарным поиском, можно добиться асимптотики
![$O(nlogn)$ $O(nlogn)$](https://dxdy-04.korotkov.co.uk/f/7/4/3/743c00b1fa7d59c887892656948b54b882.png)
.
Набросок решения за
![$O(n)$ $O(n)$](https://dxdy-02.korotkov.co.uk/f/1/f/0/1f08ccc9cd7309ba1e756c3d9345ad9f82.png)
.
Положим
![$\Delta t_i = t_i - t_{i - 1}$ $\Delta t_i = t_i - t_{i - 1}$](https://dxdy-02.korotkov.co.uk/f/1/b/0/1b0797df12489367d8fb941a6fb6b6d782.png)
.
Рассмотрим интеграл кусочно-линейной функции по некоторому отрезку
![$[a, b]$ $[a, b]$](https://dxdy-04.korotkov.co.uk/f/b/d/4/bd4455e79810acc06e3d31c60fb8bfb282.png)
, интеграл это площадь под графиком, значит это сумма площадей трапеций. Он распадается на две части, первая - между двумя точками из сетки
![$\{t_n\}$ $\{t_n\}$](https://dxdy-04.korotkov.co.uk/f/f/9/e/f9ece8814b653d4d0808a8c05ce7b69d82.png)
, и два маленьких кусочка по краям (первая часть это часть между крайними точками сетки, которые попадают в отрезок).
Интеграл по двум маленьким кусочкам считается за
![$O(1)$ $O(1)$](https://dxdy-02.korotkov.co.uk/f/1/e/2/1e2f931ee6c0b8e7a51a7b0d123d514f82.png)
, а интеграл между узлами сетки можно подсчитать за
![$O(n)$ $O(n)$](https://dxdy-02.korotkov.co.uk/f/1/f/0/1f08ccc9cd7309ba1e756c3d9345ad9f82.png)
, если предподсчитать кумулятивные суммы
![$S_k = \sum\limits_{i = 1}^{i < k} x_i (t_{i + 1} - t_{i - 1})$ $S_k = \sum\limits_{i = 1}^{i < k} x_i (t_{i + 1} - t_{i - 1})$](https://dxdy-01.korotkov.co.uk/f/0/a/4/0a4c3b78cf05ff3293793d39f40a4fe182.png)
, тогда интеграл между узлами сетки
![$t_l, t_r$ $t_l, t_r$](https://dxdy-03.korotkov.co.uk/f/2/2/f/22ffecc3054a457eb7857984a935fc4782.png)
выразится как
![$S_{l + 1} - S_{r} + x_l \Delta t_{l + 1} + x_r \Delta t_r$ $S_{l + 1} - S_{r} + x_l \Delta t_{l + 1} + x_r \Delta t_r$](https://dxdy-01.korotkov.co.uk/f/c/1/d/c1de2afdd6a99dda2b37edf917575f3b82.png)
(могу написать выкладку, как это получилось, подробно, если кратко - это получится, если в выражении для интеграла привести подобные члены по
![$x_i$ $x_i$](https://dxdy-02.korotkov.co.uk/f/9/f/c/9fc20fb1d3825674c6a279cb0d5ca63682.png)
).
Массив кумулятивных сумм считается за один проход, то есть
![$O(n)$ $O(n)$](https://dxdy-02.korotkov.co.uk/f/1/f/0/1f08ccc9cd7309ba1e756c3d9345ad9f82.png)
, потом за второй проход считаем интеграл.
Пока не ясен один момент - как определять
![$l$ $l$](https://dxdy-03.korotkov.co.uk/f/2/f/2/2f2322dff5bde89c37bcae4116fe20a882.png)
и
![$r$ $r$](https://dxdy-01.korotkov.co.uk/f/8/9/f/89f2e0d2d24bcf44db73aab8fc03252c82.png)
для данных
![$a, b$ $a, b$](https://dxdy-02.korotkov.co.uk/f/5/f/8/5f8c6707c3c404791835c4d82736cf4f82.png)
, если делать это бинарным поиском, то итоговая асимптотика получится
![$O(nlogn)$ $O(nlogn)$](https://dxdy-04.korotkov.co.uk/f/7/4/3/743c00b1fa7d59c887892656948b54b882.png)
. Скорее всего их можно определять адаптивно, используя информацию на предыдущих шагах, но я пока не придумал, как именно.
Вопрос - можно ли решить эту задачу за
![$O(n)$ $O(n)$](https://dxdy-02.korotkov.co.uk/f/1/f/0/1f08ccc9cd7309ba1e756c3d9345ad9f82.png)
? И как её правильно решать? Если пытаться закодить вышеописанный алгоритм, получается какой-то монстр (походу я слишком криво его реализую). Возможно я изобретаю велосипед, и эта задача имеет решение каким-нибудь известным алгоритмом.