|
| 1 | +#include <bits/stdc++.h> |
| 2 | +#define ll long long |
| 3 | +using namespace std; |
| 4 | + |
| 5 | +/* |
| 6 | + * POINT UPDATE, RANGE QUERY |
| 7 | + */ |
| 8 | + |
| 9 | +// Add delta to A[index] |
| 10 | +void point_update(vector<ll> &bit, ll index, ll delta) { |
| 11 | + for(;index < bit.size(); index += (index & -index)) { |
| 12 | + bit[index] += delta; |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +// Query sum of A[1..index] |
| 17 | +ll prefix_sum(vector<ll> &bit, ll index) { |
| 18 | + ll sum = 0; |
| 19 | + for(;index > 0; index -= (index & -index)) { |
| 20 | + sum += bit[index]; |
| 21 | + } |
| 22 | + return sum; |
| 23 | +} |
| 24 | + |
| 25 | +// Query sum of A[a..b] |
| 26 | +ll range_query(vector<ll> &bit, ll a, ll b) { |
| 27 | + return prefix_sum(bit,b) - prefix_sum(bit,a-1); |
| 28 | +} |
| 29 | + |
| 30 | +/* |
| 31 | + * RANGE UPDATE, POINT QUERY |
| 32 | + */ |
| 33 | + |
| 34 | +// Add delta to A[a..b] |
| 35 | +void range_update(vector<ll> &bit, ll a, ll b, ll delta) { |
| 36 | + point_update(bit,a,delta); |
| 37 | + point_update(bit,b+1,-delta); |
| 38 | +} |
| 39 | + |
| 40 | +// Returns A[index] |
| 41 | +ll point_query(vector<ll> &bit, ll index) { |
| 42 | + ll sum = 0; |
| 43 | + for(;index > 0; index -= (index & -index)) { |
| 44 | + sum += bit[index]; |
| 45 | + } |
| 46 | + return sum; |
| 47 | +} |
| 48 | + |
| 49 | +/* |
| 50 | + * RANGE UPDATE, RANGE QUERY |
| 51 | + */ |
| 52 | + |
| 53 | +// Add delta to A[a..b] |
| 54 | +void range_update(vector<ll> &bit1, vector<ll> &bit2, ll a, ll b, ll delta) { |
| 55 | + range_update(bit1,a,b,delta); |
| 56 | + point_update(bit2,a,delta * (a-1)); |
| 57 | + point_update(bit2,b+1,-delta * b); |
| 58 | +} |
| 59 | + |
| 60 | +// Query sum of A[1..index] |
| 61 | +ll prefix_sum(vector<ll> &bit1, vector<ll> &bit2, ll index) { |
| 62 | + return prefix_sum(bit1,index) * index - prefix_sum(bit2,index); |
| 63 | +} |
| 64 | + |
| 65 | +// Query sum of A[a..b] |
| 66 | +ll range_query(vector<ll> &bit1, vector<ll> &bit2, ll a, ll b) { |
| 67 | + return prefix_sum(bit1, bit2, b) - prefix_sum(bit1, bit2, a-1); |
| 68 | +} |
| 69 | + |
| 70 | + |
| 71 | +// Slightly optimized to read a single value |
| 72 | +// Returns A[index] |
| 73 | +ll read_single_value(vector<ll> &bit, ll index) { |
| 74 | + ll sum = bit[index]; |
| 75 | + if (index > 0) { |
| 76 | + ll z = index - (index & -index); |
| 77 | + index--; |
| 78 | + while (index != z) { |
| 79 | + sum -= bit[index]; |
| 80 | + index -= (index & -index); |
| 81 | + } |
| 82 | + } |
| 83 | + return sum; |
| 84 | +} |
| 85 | + |
| 86 | +int main() { |
| 87 | + ll i,n,q,v,l,r; |
| 88 | + cin >> n; |
| 89 | + vector<ll> bit(n+1,0); |
| 90 | + for (i = 1; i <= n; i++) { |
| 91 | + cin >> v; |
| 92 | + point_update(bit,i,v); |
| 93 | + } |
| 94 | + cin >> q; |
| 95 | + for (i = 0; i < q; i++) { |
| 96 | + cin >> l >> r; |
| 97 | + cout << "Sum of range [" << l << "," << r << "] = " << range_query(bit,l,r) << endl; |
| 98 | + cout << "Value at " << l << " = " << read_single_value(bit,l) << endl; |
| 99 | + cout << "Value at " << r << " = " << read_single_value(bit,r) << endl; |
| 100 | + } |
| 101 | + return 0; |
| 102 | +} |
0 commit comments