Editorial for COCI '19 Contest 2 #4 Popcount
Submitting an official solution before solving the problem yourself is a bannable offence.
Esoteric programming language, only one variable, constraints on source code length, looks like a perfect combination for solving "subtask by subtask".
In the first subtask, we're allowed to use the number of commands that is (almost) the same as the number of bits of the input value. This suggests that we could solve the subtask "bit by bit". Let's assume that we have successfully solved the suffix of bits, i.e., that suffix of
now contains the number of ones in the corresponding suffix of input value while the other bits of
remain unchanged with regards to the input value. Note that the input value itself already has a solved suffix of size
. Suffix of size
bits will be solved by adding the value of bit
to the variable
while also setting that bit to
. We can do that using the following command
A=((A&(((1<<N)-1)-(1<<X)))+((A&(1<<X))>>X))
. We could have solved the first subtask by using commands of this form.
To solve the second subtask, we can use the same idea from the first subtask along with the fact that variable can be found at most
times in the right side of the command. Therefore, instead of solving the task "bit by bit", we will solve it using the technique "four bits by four bits". This will reduce the number of used commands
times.
To solve the remaining subtask, we could use an idea from the famous data structure, the segment tree. Let's imagine that we have built a segment tree on top of our bit number. Each node of the tree will store the sum of bits (number of ones) in its subtree. Imagine also that those values are written in binary with the number of bits that corresponds to the length of the interval (segment) which is covered by that node.
If we were to glue the values of all leaves (from left to right) in our segment tree, we would get the input value into our program. If we glue the values of their parents in the same way, we will get the wanted value of number after our first command. If we were to repeat this process until the root, we will in the end store the correct value in variable
by using an order of
commands, which should be enough for the last two subtasks. The only thing left to do is to find the command which makes the transition from one set of nodes to their parents in the segment tree.
For the first command, we could have taken all bits at even indices and add to them all bits at odd indices shifted to the right by one. We can do that with the expression ((...01010101&A)+((...10101010&A)>>1))
. In the next step (intervals of length ) the expression could be
((...00110011&A)+((...11001100&A)>>2))
. By repeating this pattern, we will solve the task using commands, each of which has two occurrences of
in them.
In this task, for the sake of implementation, we suggest using Python or Java.
Comments