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