Radnici u jednoj meteorološkoj stanici su napravili vremensku prognozu koja predviđa temperaturu za narednih \(n\) dana. Od značaja su im naredni upiti:
Implementirati program koji efikasno realizuje pomenute upite. Podrazumevati da indeksi dana kreću od 1.
Sa standardnog ulaza se unosi broj dana \(n\) (\(1 \le n \le 10000\)), a zatim i predviđene temperature (realni brojevi) za narednih \(n\) dana. Nakon toga se unosi broj upita \(m\) (\(1 \le m \le 1000\)), a zatim i \(m\) upita u već opisanom formatu.
Za svaki od upita druge vrste ispisati prosečnu temperaturu u zasebnom redu.
5 22.4 25.1 27.2 31.1 28.5 3 p 2 4 u 3 28.1 p 2 4
27.8 28.1
U ovom bloku se opisuje glavno rešenje zadatka.
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <limits>
#include <cmath>
using namespace std;
void build(vector<double> &tree, const vector<double> &arr,
const int i, const int start, const int end)
{
if (start == end) {
tree[i] = arr[start];
return;
}
int mid = (start + end) / 2;
build(tree, arr, 2 * i + 1, start, mid);
build(tree, arr, 2 * i + 2, mid + 1, end);
tree[i] = tree[2*i + 1] + tree[2*i + 2];
}
void build(vector<double> &tree, const int n, const vector<double> &arr)
{
build(tree, arr, 0, 0, n - 1);
}
double query(const vector<double> &tree,
const int i, const int start, const int end,
const int l, const int r)
{
if (r < start || l > end) {
return 0;
}
if (l <= start && r >= end) {
return tree[i];
}
int mid = (start + end) / 2;
double sum_left = query(tree, 2 * i + 1, start, mid, l, r);
double sum_right = query(tree, 2 * i + 2, mid + 1, end, l, r);
return sum_left + sum_right;
}
double query(const vector<double> &tree, const int n,
const int l, const int r)
{
return query(tree, 0, 0, n - 1, l, r);
}
void update(vector<double> &tree,
const int i, const int start, const int end,
const int ind, const double val)
{
if (start == end) {
tree[i] = val;
return;
}
int mid = (start + end) / 2;
if (ind <= mid) {
update(tree, 2 * i + 1, start, mid, ind, val);
} else {
update(tree, 2 * i + 2, mid + 1, end, ind, val);
}
tree[i] = tree[2*i + 1] + tree[2*i + 2];
}
void update(vector<double> &tree, const int n,
const int ind, const double val)
{
update(tree, 0, 0, n - 1, ind, val);
}
int main(void)
{
int n;
cin >> n;
vector<double> arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
const int height = ceil(log2(n));
const int size = 2 * pow(2, height) - 1;
vector<double> tree(size);
build(tree, n, arr);
int q;
cin >> q;
while (q--) {
char op; cin >> op;
if (op == 'u') {
int ind;
double val;
cin >> ind >> val;
update(tree, n, ind-1, val);
} else if (op == 'p') {
int l, r; cin >> l >> r;
double sum = query(tree, n, l-1, r-1);
cout << sum / (r - l + 1) << endl;
}
}
return 0;
}