Editorial for UTS Open '18 P6 - Subset Sum


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: PlasmaVortex

Subtask 1

The condition AXB is equivalent to (a&x)=a and (b&x)=x, which can be checked on O(1) time (here, & denotes the bitwise AND operation). For each type 2 query, we can loop through all 2N subsets and add its value to the total if it satisfies this condition.

Time Complexity: O(Q2N)

Subtask 2

If we treat the 2N identifiers as vertices of an N-dimensional hypercube, we can create an N-dimensional prefix sum array in O(N2N) by calculating a prefix sum in each dimension. More specifically, for each i (0i<N), for all integers x with ith bit 0, add arr[x] to arr[x+2i]. Now arr[a] will be the sum of the values of all X such that XA.

Split the queries into Q blocks of size Q. At the start of each block, initialize the prefix sum array as above. Keep a list of the updates that have occurred, and when querying a set A, return arr[a] with adjustments for any set XA whose value was updated (there are at most Q of them if you reset the list of updates each block).

Time Complexity: O((N2N+Q)Q)

Subtask 3

Let x[i] denote the ith bit of x. For each query (A,B), we need (a&b)=a, otherwise the answer to the query would be 0. This means there are 3 possibilities for (a[i],b[i]): either (0,0), (0,1), or (1,1). Let x1 and x2 be the first and second halves of the binary representation of an integer x. We can 'join' the a1 and b1 to get a ternary number join(a1,b1), where the ith digit of join(a1,b1) is 0 if (a1[i],b1[i])=(0,0), 1 if (a1[i],b1[i])=(0,1), or 2 if (a1[i],b1[i])=(1,1). Similarly, we can convert back, going from any N/2-digit ternary integer c to a corresponding pair of N/2-bit integers a and b, with (a&b)=a and join(a,b)=c.

Now, define the array arr[c][d2] as the sum of the values of all N-bit integers d, whose second half (in binary) is d2, and whose first half d1 satisfies (a&d1)=a and (b&d1)=d1, where a and b are the pair of integers such that (a&b)=a and join(a,b)=c. When the value of s changes by v, we can update this array in O(2N/2) by adding v to arr[join(a,b)][s2], for all a,b such that (a&s1)=a and (b&s1)=s1 (there are exactly 2N/2 such pairs a,b). To answer the query (a,b), we add up arr[join(a1,b1)][x2] for all x2 such that (a2&x2)=a2 and (b2&x2)=x2, which is also O(2N/2). Note that we can precalculate join(a,b) in O(N3N/2), and array arr can be efficiently initialized in O(6N/2) (alternatively, you can initialize with all 0's and update 2N times).

Time Complexity: O(Q2N/2+6N/2)


Comments

There are no comments at the moment.