Neka je dat niz celih brojeva \(a\) dužine \(n\). Postoje dva tipa upita:
Sa standardnog ulaza se unose celi brojevi \(n\) i \(q\), a zatim i \(n\) elemenata niz \(a\). Nakon toga unosi se \(q\) upita. Svaki upit \(j=1,\ldots,q\) čini tip upita \(t_j \in \{ u, s \}\) i argumenti. Ukoliko je tip upita \(t_j = u\), argumenti upita \(j\) su indeks \(i_j\) (\(0 \leq i_j < n\)) i vrednost \(x_j\), a ukoliko je tip upita \(t_j = s\), argumenti upita \(j\) su indeksi \(l_j\) i \(r_j\) (\(0 \leq l_j \leq r_j < n\)). Pretpostaviti da je broj upita prvog tipa mnogo manji od broja upita drugog tipa.
Za svaki upit drugog tipa ispisati traženu sumu.
8 4 3 1 4 1 5 9 2 6 s 1 3 s 0 4 u 1 4 s 0 4
6 14 17
Pod pretpostavkom da je broj upita prvog tipa mnogo manji od broja upita drugog tipa, zadatak možemo rešiti pomoću prefiksnih suma. Neka je niz prefiksnih suma \(p\), tj. za svako \(i\) važi \(p_i = \sum_{j=0}^i a_j\). Niz prefiksnih suma možemo inkrementalno sagraditi u vremenskoj složenosti \(O(n)\). Za prvi tip upita \(i\)-tom elementu treba dodeliti novu vrednost, tj. \(a_i \gets x\). Tada treba ažurirati i niz prefiksnih suma \(p\). Složenost ove operacije je \(O(n)\). Drugi tip upita rešavamo tako što iskoristimo niz prefiksnih suma. Naime, važi \(\sum_{j=l}^r a_j = \sum_{j=0}^r a_j - \sum_{j=0}^{l-1} a_j = p_r - p_{l-1}\), za \(l>0\), kao i \(\sum_{j=l}^r a_j = \sum_{j=0}^r a_j = p_r\), za \(l = 0\). Složenost ove operacije je \(O(1)\). Kako je broj upita prvog tipa mnogo manji od broja upita drugog tipa, algoritam možemo smatrati da je složenosti \(O(n + q)\), ali je on suštinski složenosti \(O(nq)\).
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main(void)
{
int n, q;
>> n >> q;
cin
<int> a(n);
vectorfor (int i = 0; i < n; i++) {
>> a[i];
cin }
<int> p(n);
vector(a.cbegin(), a.cend(), p.begin());
partial_sum
for (int i = 0; i < q; i++) {
;
string query>> query;
cin
if (query == "u") {
int ind, val;
>> ind >> val;
cin
[ind] = val;
a(a.cbegin(), a.cend(), p.begin());
partial_sum} else if (query == "s") {
int l, r;
>> l >> r;
cin
<< (l == 0 ? p[r] : p[r] - p[l - 1]) << endl;
cout }
}
return 0;
}