\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
İndi dispersiya düsturunu aşağıdakı şəklə gətirə bilərik:
\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}}
Əgər ardıcıllıq üçün \{a_i, a_{i+1}, ..., a_{i+k-1}\} onun elementlərinin cəmini (a_i + a_{i+1} + ... + a_{i+k-1}) və onların kvadratları cəmini (a^2_i + a^2_{i+1} + ... + a^2_{i+k-1}) hesablamaq lazımdırsa, o zaman verilən intervallarda axtarılan dispersiyanı sabit zaman içində tapmaq mümkündür.
Misal
Dispersiya üçün kəsrin surətini n = 3 üçün dəqiqləşdirək:
\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
Alqoritmin reallaşdırılması
Giriş məlumatlarını oxuyuruq.
scanf("%d %d", &n, &k);
a.resize(n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
[i - k + 1; i] intervalında iki dəyişəni dəstəkləyirik:
cəm sum = a_{i-k+1} + ... + a_{i-1} + a_i,
kvadratlar cəmi sum2 = a^2_{i-k+1} + ... + a^2_{i-1} + a^2_i
Ardıcıllığın elementlərini ardıcıllıqla nəzərdən keçiririk.
for (i = 0; i < n; i++)
{
sum və sum2 dəyərlərini yeniləyirik.
sum += a[i];
sum2 += a[i] * a[i];
k yoxsa intervalda [i - k + 1; i] varsa, onun üçün cavabı çap edirik.
if (i >= k - 1)
{
printf("%lf\n", sqrt((sum2 - (sum * sum) / k) / (k - 1)));
Nəzərdən keçirilən ardıcıllıqdan i - k + 1 indeksli elementi silirik.
sum -= a[i - k + 1];
sum2 -= a[i - k + 1] * a[i - k + 1];
}
}