11317. K-дисперсия
Рассмотрим дисперсию
последовательности a1, a2, ..., an как

где

Рассмотрим K-дисперсию как
дисперсию непрерывной подпоследовательности длины k.
Ваша задача – вычислить все (n
– k + 1) K-дисперсии для заданной последовательности и k.
Формально, i-ой (1 ≤
i ≤ n – k + 1) K-дисперсией ri
является дисперсия последовательности {ai,
ai+1, ..., ai+k-1}.
Вход. Первая строка содержит два целых
числа n и k (2 ≤ k ≤ n ≤
105).
Вторая строка содержит n целых
чисел a1, a2, ..., an
(|ai| ≤ 100).
Выход. Выведите (n – k +
1) строк – действительные числа r1, r2,
..., rn−k+1.
Ответ считается правильным, если
его абсолютная или относительная погрешность не превышает 10-4.
| 
   Пример
  входа 1  | 
  
   Пример
  выхода 1  | 
 
| 
   3 2 1 3 2  | 
  
   1.41421356 0.70710678  | 
 
| 
   | 
  
   | 
 
| 
   Пример
  входа 2  | 
  
   Пример
  выхода 2  | 
 
| 
   5 3 1 3 2 4 5  | 
  
   1.00000000 1.00000000 1.52752523  | 
 
математика
Рассмотрим сумму:
 = 
 = 
 = 
 – 
 + 
 =
 – 
 + 
 = 
 – ![]()
Теперь формулу дисперсии можно переписать в виде:
 = 
Если для последовательности {ai, ai+1,
..., ai+k−1} поддерживать
сумму ее элементов (ai + ai+1
+ ... + ai+k−1) и сумму ее квадратов
(
),
то за константное время можно вычислить искомую дисперсию на отрезке .
Пример
Распишем числитель дроби в дисперсии для n
= 3:
 + 
 + 
 =
= 
 – 
  – 
  – 
 +
+ 
 + 
+ 
 =
= 
 – 
 + 
 =
= 
 – 
 + 
 =
= 
 – ![]()
Реализация алгоритма
Читаем входные данные.
scanf("%d %d", &n, &k);
a.resize(n);
for (i = 0; i < n; i++)
  scanf("%d", &a[i]);
На
отрезке [i – k
+ 1; i] поддерживаем две переменные:
·       
сумму sum = ai-k+1 + … + ai-1 + ai,
·       
сумму квадратов sum2 = ![]()
sum = sum2 = 0;
Перебираем
элементы последовательности.
for (i = 0; i < n; i++)
{
Обновляем
значения sum и sum2.
  sum += a[i];
  sum2 += a[i] * a[i];
Если
имеется окно [i – k
+ 1; i] длины k, то выводим ответ для него.
  if (i >= k - 1)
  {
   
printf("%lf\n", sqrt((sum2 - (sum * sum) / k) / (k - 1)));
Удаляем
из рассматриваемой последовательности элемент с индексом i – k + 1.
    sum -= a[i - k +
1];
    sum2 -= a[i - k + 1] * a[i - k +
1];
  }
}