Editorial for Back From Summer '17 P5: Confusing Codeforces Contest
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Subtask 1
Since , we can simply try every single path by doing depth first search, and check if the edge is blocked before proceeding.
Runtime complexity:
Subtask 2
Since , we can create a matrix representing links (or blocked links) between people. Note that the ways to get to person #N
is the sum of ways to get to person #i
where is not blocked. Therefore, we can use dynamic programming to memorize the solutions for people before.
Runtime complexity:
Subtask 3
The big difference from the last subtask is that the number of ways to add has gotten much larger, but the number of blocked links has not increased much. We can take advantage of this by maintaining the sum of all previous elements, and subtracting the blocked links instead. To avoid duplicate deletions, we can use a set or similar data structure to maintain all the unique blocked links for each person.
Runtime complexity:
Subtask 4
Let us mark each person with a bitset (binary number) from to to indicate the sets covering it. A bit will be on to indicate the person is in the group, and off otherwise. Two people are in the same group only if they overlap on at least 1 bit. In other words, . After we solve a person, we can store their path count inside an array of size . When we try to solve for another person, we can loop through the array and subtract from the indices that share at least one bit with the binary number of that person.
Runtime complexity:
Subtask 5
The same idea is used as subtask 4, however, we can't pass using the same method as , which is way too big to run within the time limit. To get around this, we need to create a data structure which can efficiently update and query the sums from indices that share at least one bit.
To solve queries, we first need to update. To do this, we can split the -bit binary number into pieces of bits each. Let us call those part and part .
First, we create an array of . Let us call it .
To update, we go through each integer from to . If , update , otherwise update .
This way, contains the sum of all numbers in the form where . Meanwhile, contains the sum of all numbers in the form where .
First, we add since that contains all numbers that share a bit in the first bits. To account for the remaining numbers that do not share the first bits, but share some of the last bits, we go through for all where .
Using this data structure, we can update and query in time.
This is sufficient to solve for the last subtask.
Runtime complexity:
Comments