Let’s consider the sum:
\sum_{i=1}^n (a_i - \bar{a})^2 = \sum_{i=1}^n \left(a_i - \frac{\sum_{i=1}^n a_i}{n} \right)^2 = \sum_{i=1}^n \left(a^2_i - \frac{2}{n} a_i \sum_{i=1}^n a_i + \frac{\left(\sum_{i=1}^n a_i \right)^2}{n^2} \right) = \\
\sum_{i=1}^n a^2_i - \frac{2}{n} \sum_{i=1}^n a_i \sum_{i=1}^n a_i + \frac{\left(\sum_{i=1}^n a_i \right)^2}{n} = \\
\sum_{i=1}^n a^2_i - \frac{2}{n} \left(\sum_{i=1}^n a_i \right)^2 + \frac{1}{n} \left(\sum_{i=1}^n a_i \right)^2 = \sum_{i=1}^n a^2_i - \frac{1}{n} \left(\sum_{i=1}^n a_i \right)^2
Now, the formula for variance can be rewritten as:
\sqrt{\sum_{i=1}^n (a_i - \bar{a})^2 \over n - 1} = \sqrt{\frac{\sum_{i=1}^n a^2_i - \frac{1}{n} \left(\sum_{i=1}^n a_i \right)^2}{n - 1}}
If we maintain the sum of the elements of the sequence \{a_i, a_{i+1}, ..., a_{i+k-1}\} (i.e. (a_i + a_{i+1} + ... + a_{i+k-1})) and the sum of their squares (a^2_i + a^2_{i+1} + ... + a^2_{i+k-1}), then it is possible to calculate the desired variance for the segment in constant time.
Example
Let's expand the numerator of the fraction in the variance n = 3:
\left(a_1 - \frac{a_1 + a_2 + a_3}{3}\right)^2 + \left(a_2 - \frac{a_1 + a_2 + a_3}{3}\right)^2 + \left(a_3 - \frac{a_1 + a_2 + a_3}{3}\right)^2 = \\
a_1^2 + a_2^2 + a_3^2 - 2a_1 \cdot \frac{a_1 + a_2 + a_3}{3} - 2a_2 \cdot \frac{a_1 + a_2 + a_3}{3} - 2a_3 \cdot \frac{a_1 + a_2 + a_3}{3} + \\
\left(\frac{a_1 + a_2 + a_3}{3}\right)^2 + \left(\frac{a_1 + a_2 + a_3}{3}\right)^2 + \left(\frac{a_1 + a_2 + a_3}{3}\right)^2 = \\
a_1^2 + a_2^2 + a_3^2 - \frac{2}{3}(a_1 + a_2 + a_3)(a_1 + a_2 + a_3) + 3 \cdot \left(\frac{a_1 + a_2 + a_3}{3}\right)^2 = \\
a_1^2 + a_2^2 + a_3^2 - \frac{2}{3}(a_1 + a_2 + a_3)^2 + \frac{1}{3}(a_1 + a_2 + a_3)^2 = \\
a_1^2 + a_2^2 + a_3^2 - \frac{1}{3}(a_1 + a_2 + a_3)^2
Algorithm implementation
Read the input data.
scanf("%d %d", &n, &k);
a.resize(n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
On the segment [i - k + 1; i] let's maintain two variables:
The sum sum = a_{i-k+1} + ... + a_{i-1} + a_i,
The sum of squares sum2 = a^2_{i-k+1} + ... + a^2_{i-1} + a^2_i
Iterate through the elements of the sequence.
for (i = 0; i < n; i++)
{
Update the values of sum and sum2.
sum += a[i];
sum2 += a[i] * a[i];
If there is a window [i - k + 1; i] of length k, print the result for it.
if (i >= k - 1)
{
printf("%lf\n", sqrt((sum2 - (sum * sum) / k) / (k - 1)));
Remove the element with index i - k + 1 from the considered sequence.
sum -= a[i - k + 1];
sum2 -= a[i - k + 1] * a[i - k + 1];
}
}