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