Skip to content

Commit 232d77e

Browse files
Add Tutorial for LOJ-1369: Answering Queries (en) (#443)
* Added tutorial for LOJ-1369 Answering Queries * Format 1369 --------- Co-authored-by: Rafid Bin Mostofa <[email protected]>
1 parent c14d00d commit 232d77e

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

1369/en.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# LOJ 1369 - Answering Queries
2+
3+
First let's understand what the given code is doing.
4+
There will be two types of queries, one is calculating the sum and the other
5+
one is to change the value of an element of the given array `A[]`.
6+
If you calculate the sum in the way the given code does, the complexity of
7+
the code will be O(t * q * n * n), which will not fit in the Time limit.
8+
So, we need to do the same thing what the given code does but in an efficient
9+
way. But what that way could be? Let's see!
10+
11+
We can use _contribution technique_ to solve this problem. Firstly, we will
12+
determine how much contribution an element of the array does to the `sum`.
13+
14+
For example, let's take an array of four elements {1, 4, -2, 8}.
15+
The `sum` will be the summation of (1-4) + (1-(-2)) + (1-8), (4-(-2)) + (4-8) and (-2-8).
16+
Here first element is summed for 3 times and subtracted for 0 times,
17+
so the contribution of 1 to the `sum` is 3 - 0 = 3.
18+
Again second element is summed for 2 times and subtracted for 1 times,
19+
so the contribution of 4 to the `sum` is 2 - 1 = 1.
20+
In the same way, the contributions of the third element -2
21+
and fourth element 8 to the `sum` are -1 and -2 respectively.
22+
23+
So, in this way we will calculate the contribution of each element of the
24+
array to the `sum` and store it to an array named `contribution[n]`.
25+
_How can we do that?_
26+
27+
Observe the pattern: each element is summed for the exact same number of
28+
elements it has after it and that number will be `(n - index - 1)`.
29+
In the same way, each element is subtracted for the exact same number of
30+
elements it has before it and that number is the index of that element `index`.
31+
So we can calculate the contribution of each element in this way:
32+
```
33+
contribution[index] = (n - index - 1) - index;
34+
```
35+
36+
Now we can calculate the `sum` by going through every element of the array
37+
and add `A[index] * contribution[index]` to the sum.
38+
Even if the value of an element changes, the corresponding value in the
39+
`contribution` array of that element will still remain the same, because
40+
`contribution` array has nothing to do with elements' value rather it
41+
tells us how `sum` is calculated.
42+
43+
So, when the query will be to change the value of an element, we will just
44+
recalculate the `sum` in the following manner in constant time,
45+
no need to loop over the whole array.
46+
47+
```
48+
sum -= arr[x] * contribution[x];
49+
arr[x] = v;
50+
sum += arr[x] * contribution[x];
51+
```
52+
53+
The time complexity of this approach will be O(t * (n + q)). _How?_
54+
55+
### C++ Code
56+
57+
```cpp
58+
59+
/*
60+
Author: Arup Debnath
61+
Date: 24 March, 2023
62+
63+
Happy Coding!!
64+
*/
65+
66+
#include <bits/stdc++.h>
67+
#define N ((int)1e5 + 5)
68+
69+
using namespace std;
70+
71+
int A[N];
72+
int contribution[N];
73+
74+
int main()
75+
{
76+
ios_base::sync_with_stdio(false);
77+
cin.tie(NULL);
78+
79+
int t;
80+
cin>>t;
81+
for(int i = 1; i <= t; i++) {
82+
int n, q;
83+
cin>>n>>q;
84+
85+
long long sum = 0;
86+
87+
for(int j = 0; j < n; j++) {
88+
cin>>A[j];
89+
contribution[j] = (n-j-1) - j;
90+
sum += 1LL * A[j] * contribution[j];
91+
// multiplying by 1LL is important because A[j] * contribution[j]
92+
// can be greater than INT_MAX (2^31 - 1)
93+
}
94+
95+
cout << "Case " << i << ":\n";
96+
while(q--) {
97+
int type;
98+
cin>>type;
99+
if(type == 0) {
100+
int idx, val;
101+
cin>>idx>>val;
102+
sum -= 1LL * A[idx] * contribution[idx];
103+
A[idx] = val;
104+
sum += 1LL * A[idx] * contribution[idx];
105+
} else {
106+
cout << sum << "\n";
107+
}
108+
}
109+
}
110+
}
111+
```

0 commit comments

Comments
 (0)