Kevin has three children and he wants to buy chocolates for them. The shopkeeper has ‘N’ boxes of chocolates (numbered from 1 to ‘N’). Each box has some amount of chocolates. If Kevin selects the “i-th” box for buying the chocolates then he must have to buy all the chocolates present in that box. Kevin wants to distribute an equal amount of chocolates among his children.
This problem is divided into 3 subproblems. You must have to solve all three subproblems.
FIRST:
You have to find the maximum number of ways in which Kevin can buy the chocolates if he is allowed to choose boxes in random order.
SECOND:
You have to find the maximum number of ways in which Kevin can buy the chocolates if he is only allowed to choose the consecutive boxes.
THIRD:
There are ‘Q’ queries given to you and each query can be of two types:
0 I V
1 L R
The first type has 0 as a first character that represents this is an update query in which you have to update the number of chocolates in the “Ith” box to ‘V’.
The second type has 1 as a first character that represents this is a range query in which you have to find the maximum number of ways in which Kevin can buy the chocolates in the range [L, R] if he is allowed to choose boxes in any order.
Note:
1. There is no need to maximize the number of chocolates bought by Kevin.
2. Consider 1 based indexing for queries. There must be a single query of type 1.
3. You have to take the modulo with 10^9 + 7 as the result can be very large.
The first line contains a single integer ‘T’ representing the number of test cases.
The first line of each test case will contain a single integer ‘N’ which denotes the number of chocolate boxes in the shop.
The second line of each test case contains ‘N’ space-separated integers which denote the number of chocolates in a particular box.
The third line of each test case will contain a single integer ‘Q’ which denotes the number of queries.
The next ‘Q’ lines contain three integers “0 I V” or “1 L R” in which ‘I’ represents the index whose value will have to be updated to ‘V’. ‘L’ and ‘R’ represent the inclusive range for which the result has been asked.
Output Format:
For each test case, print the result of all three subproblems in order such that:
In the first line, the result of subproblem 1 (FIRST) is printed.
In the second line, the result of subproblem 2 (SECOND) is printed.
In the third line, the result of each range query of type 1 is printed and each integer must be separated by a single space.
Output for every test case will be printed in a separate line.
Note:
You don’t need to print anything; It has already been taken care of. Just implement the given function.
1 <= T <= 10
1 <= N <= 100
1 <= ARR[ i ] <= 10^5
1 <= Q <= 100
1 <= I, L, and R <= N
1 <= V <= 10^5
Where "ARR[i]” is the number of chocolates in the “i-th” box, ‘Q’ is the number of queries, and ‘I’, ‘V’, ‘L’, and ‘R’ are described in the Input format.
Time limit: 1 sec
1
4
2 3 5 8
2
0 1 3
1 1 3
3
2
3
In the first test case, the number of ways in which Kevin can buy the chocolates if he chooses boxes in any order is 3 ([2, 5, 8], [3], [2, 3, 5, 8]), if he chooses only consecutive boxes then answer is 2 ([2, 3, 5, 8] and [3]) and after updating the array answer for the range query is 3 ([3], [3], [3,3]).
2
1
12
4
0 1 2
1 1 1
0 1 3
1 1 1
3
3 1 3
2
0 2 3
1 1 3
1
1
0 1
3
2
7
In the second test case, Results for each subproblem are as follows:
FIRST :- [3], [3, 3], and [3].
SECOND :- [3], and [3]
THIRD :- [3], [3, 3], [3, 3], [3, 3, 3], [3], [3, 3], and [3].
Can you think of going through recursively and forming a segment tree and reach to the answer?
The first thing that we have to consider is that Kevin will only buy chocolates in the multiple of 3 because he has three children and he wants to distribute chocolates in an equal amount.
For the FIRST subproblem:
The basic idea is to go through recursively and keep counting the subsequences whose sum is divisible by 3.
We will make a helper function ( named “subsequenceOf3” ) which takes the given boxes, index of a particular box, and the current sum of chocolates as the arguments and returns the maximum number of ways in which Kevin can buy the chocolates if he chooses boxes in random order. Make sure of taking modulo with 10^9 + 7.
int subsequenceOf3 (vector<int> &arr, int ind, int sum)
Where ‘arr' is the given array/boxes, ‘ind’ is the number of boxes left, and ‘sum’ is the sum of chocolates.
The steps are as follows:
For the SECOND subproblem:
The basic idea is to traverse through all the subarrays using a nested loop and increment the counter if the sum of the elements of a particular subarray is a multiple of 3.
We are going to use an additional function (named “subarrayOf3”) which takes boxes as the input and returns the maximum number of ways in which Kevin can buy the chocolates if he can only choose consecutive boxes.
int subarrayOf3(vector<int> &arr, int N)
Where ‘ARR’ is the given array/boxes and ‘N’ is the total number of boxes.
The steps are as follows:
For the THIRD subproblem:
The basic idea is to use a segment tree to find the maximum number of ways in which Kevin can buy the chocolates within a range ['L', ‘R’] (inclusive) if he chooses boxes in any order (means we have to find the number of subsequences having sum divisible by 3). We will store three integer variables at each node by using struct (in case of CPP):
struct node {
int rem0 ( it stores the frequency of numbers having remainder 0 when divided by 3).
int rem1 ( it stores the frequency of numbers having remainder 1 when divided by 3).
int rem2 ( it stores the frequency of numbers having remainder 2 when divided by 3).
}
For Reference: https://cp-algorithms.com/data_structures/segment_tree.html
And, the merge function (receives two nodes n1 and n2) is used to find the merged node which computes new rem0, rem1, and rem2 by taking modulo with 10^9+7 as:
new rem0 = ((n1.rem0 * n2.rem0)%mod + (n1.rem1 * n2.rem2)%mod + (n1.rem2 * n2.rem1)%mod + n1.rem0 + n2.rem0)%mod
new rem1 = ((n1.rem0 * n2.rem1)%mod + (n1.rem1 * n2.rem0)%mod + n1.rem1 + n2.rem1 + (n1.rem2 * n2.rem2)%mod)%mod
new rem2 = ((n1.rem0 * n2.rem2)%mod + (n1.rem2 * n2.rem0)%mod + n1.rem2 + n2.rem2 + (n1.rem1 * n2.rem1)%mod)%mod
Where ‘mod’ is equal to 10^9+7.
The steps are as follows:
For the FIRST subproblem:
Since we are using a recursive function and in the worst case we are making two recursive calls at each step and so, the time complexity will be O(2^N).
For the SECOND subproblem:
Since we are using a nested loop to traverse through each subarray and so, the time complexity will be O(N^2).
For the THIRD subproblem:
Since we are using the segment tree technique which will take O(log(N)) time for query and update and O(N*log(N)) time for build and so, the time complexity will be O((N+Q)*log(N)).
For the FIRST subproblem:
Since the height of the recursion tree can go up to ‘N’ in the worst case and so, the space complexity will be O(N).
For the SECOND subproblem:
Since we are not using any extra space and so, the space complexity will be O(1).
For the THIRD subproblem:
Since we are using the segment tree technique which occupies O(N) space for segment tree array and O(log(N)) space for recursive build function and so, the space complexity will be O(N*log(N)).