Редакция для Среднее на отрезке
Submitting an official solution before solving the problem yourself is a bannable offence.
1. Идея
Нужно найти среднюю температуру на отрезке дней от l до r.
Среднее значение на отрезке считается так:
- сначала находим сумму всех температур с
lпоr, - затем делим эту сумму на количество дней
r - l + 1.
Так как в условии прямо требуется использовать префиксные суммы, будем считать сумму отрезка через них.
Префиксная сумма pref[i] — это сумма первых i элементов массива. Тогда сумма на отрезке [l, r] равна:
pref[r] - pref[l - 1]
После этого остаётся только разделить на длину отрезка.
2. Наблюдения
Если считать сумму от
lдоrобычным циклом, это тоже сработает, но в задаче требуется использовать префиксные суммы.Префиксный массив удобно делать длины
n + 1, где:pref[0] = 0,pref[1] = a_1,pref[2] = a_1 + a_2,- и так далее.
Тогда формула суммы отрезка работает очень просто:
- сумма
1..r— этоpref[r], - сумма
1..(l-1)— этоpref[l-1], - значит сумма
l..r— это разностьpref[r] - pref[l-1].
- сумма
Значения
a_iмогут быть большими по модулю, до10^9, аnдо2 * 10^5, поэтому сумма может быть порядка2 * 10^14.
Значит, в C++ нужно использовать типlong long.Ответ может быть нецелым, поэтому выводить его нужно как вещественное число.
3. Алгоритм
- Считать число
n. - Считать массив температур.
- Построить массив префиксных сумм
pref:pref[0] = 0,- для каждого
iот1доn:pref[i] = pref[i - 1] + a[i - 1]в Python,- или считывать число сразу и обновлять
pref[i]в C++.
- Считать
lиr. - Найти сумму на отрезке:
sum = pref[r] - pref[l - 1]
- Найти длину отрезка:
len = r - l + 1
- Найти среднее:
ans = sum / len
- Вывести ответ с точностью
6знаков после запятой.
4. Почему это работает
По определению префиксной суммы:
pref[r]хранит сумму элементов от1доr,pref[l - 1]хранит сумму элементов от1доl - 1.
Если из суммы первых r элементов вычесть сумму первых l - 1 элементов, останется только сумма элементов от l до r.
То есть:
pref[r] = a_1 + a_2 + ... + a_rpref[l - 1] = a_1 + a_2 + ... + a_(l-1)
После вычитания получаем:
pref[r] - pref[l - 1] = a_l + a_(l+1) + ... + a_r
Это и есть сумма на нужном отрезке.
Дальше среднее значение по определению равно сумме элементов, делённой на их количество. Количество дней на отрезке [l, r] равно r - l + 1.
Значит, итоговая формула ответа:
(pref[r] - pref[l - 1]) / (r - l + 1)
Следовательно, алгоритм вычисляет именно среднюю температуру на заданном отрезке.
5. Сложность
Построение префиксных сумм занимает O(n).
Все остальные действия выполняются за O(1).
Итоговая сложность:
- по времени:
O(n) - по памяти:
O(n)
6. Код на C++17
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main() {
int n;
cin >> n;
vector<long long> pref(n + 1, 0);
for (int i = 1; i <= n; i++) {
long long x;
cin >> x;
pref[i] = pref[i - 1] + x;
}
int l, r;
cin >> l >> r;
long long sum = pref[r] - pref[l - 1];
int len = r - l + 1;
double ans = (double)sum / len;
cout << fixed << setprecision(6) << ans << "\n";
return 0;
}
7. Код на Python 3
n = int(input())
a = list(map(int, input().split()))
l, r = map(int, input().split())
pref = [0] * (n + 1)
for i in range(1, n + 1):
pref[i] = pref[i - 1] + a[i - 1]
segment_sum = pref[r] - pref[l - 1]
length = r - l + 1
answer = segment_sum / length
print(f"{answer:.6f}")
Комментарии