Editorial for Facebook Hacker Cup '15 Round 2 P4 - Fox Socks


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.

This has the foundation of a classic segment tree with lazy propagation problem, so being very familiar with that structure and algorithm is a prerequisite. It's worth noting right off the bat that all values throughout the problem (such as sock counts) can be stored modulo 10^9 throughout, and that the circular formation of the bins can be handled easily by reducing each operation that "wraps around" (when A+B-1 > N) to two operations on normal ranges (A \dots N, and 1 \dots (A+B-1-N)).

As usual, each node in the segment tree will be responsible for a contiguous range of the bins, with the main challenge being to determine what values should be stored in the node to represent its whole range, and how they can be lazily updated and queried during the various types of operations. We need each of the M operations to have a time complexity of \mathcal O(\log N).

For one thing, it's relatively clear that each node must store the total number of socks in its range. When an operation of type 1 is applied to a range, this sum can be increased using the well-known formula for the sum of an arithmetic sequence, based on the value added to the first bin in the range (C + D \times ([\text{start of the range}] - A)) and the additional value added to each subsequent bin (D). When an operation of type 2 is applied to a range, this sum can easily be reset to C multiplied by the number of bins in the range.

Keeping track of the number of bins in a node's range that contain an odd number of socks is more tricky, due to the effect of type 1 operations on this value. However, it works out well if each node separates this count into two values: the number of such bins at even and odd indices. Note that, for both even and odd indices, an operation of type 1 will either flip the parities of sock counts in all such bins, or have no effect (depending on the parity of C and D). This means that these two values can be maintained without any issue. On the other hand, an operation of type 2 will simply set both of these values to either 0 or to the number of bins with even/odd indices in the range (depending on the parity of C).

What remains is for each node to keep aggregate information about what operations have been applied to its entire range since the node has last been visited, the main principle of lazy propagation which allows not only queries but also updates to be performed on a segment tree in \mathcal O(\log N) time. It's sufficient for each node to store 1 value (the constant value) for the last type 2 operation which has been applied to it (if any), and another 2 values (the initial value and subsequent step value) for type 1 operations which have been applied since the last type 2 operation (if any). This works out due to the fact that arithmetic sequences added to a range due to type 1 operations may be added together and still represented by 2 arithmetic sequence values.


Comments

There are no comments at the moment.