Official

C - Lights Out on Tree Editorial by evima


First, the following properties about pressing buttons hold.

  • Pressing the same button twice changes nothing.
  • The order to press buttons does not matter.

These can be shown by naive arguments, but they can also be smartly explained by linear algebra on \(\text{mod }2\).

From these facts, we need to press the same button at most once, and we only need to check \(2^N\) cases: for each button, we press it or not.

Let \(B = \lbrace 1,2,\dots,N\rbrace\) be the set of all buttons. The query gives us a vertex set \(S\) and asks us to find the set of buttons \(T \subseteq B\) such that:

  • Pressing each button in \(T\) once flips exactly the coins in \(S\). \((\ast)\)

Here, the following fact holds.

For a fixed vertex set \(S\) given in a query, there is exactly one set of buttons that satisfies \((\ast)\).

First, we will show that at least one \(T\) exists.

Consider the case \(S\) is of size \(1\) and \(S = \lbrace v \rbrace\). In this case, we can see that pressing the buttons corresponding to \(v\) itself and its all children flips just \(v\). (Let \(T_v\) be this set of buttons.)

Consider a general case. Let \(S = \lbrace v_1, v_2, \dots, v_m \rbrace\). Then, the set of buttons that appear an odd number of times satisfies the requirement, which can be shown from the above property “pressing the same button twice changes nothing.” Thus, we have shown that at least one \(T\) corresponds to \(S\).

Next, we will verify that there is at most one such \(T\). There are \(2^N - 1\) possible non-empty vertex sets \(S\). On the other hand, there are \(2^N\) possible button sets, but \(T = \emptyset\) flips nothing and corresponds to no \(S\), so there are \(2^N - 1\) sets \(T\) that correspond to some \(S\). Since the number of sets that can be \(S\) is equal to the number of sets that can be \(S\), it is obvious that at most one \(T\) corresponds to each \(S\).

Therefore, it has been shown that there is always exactly one button set that satisfies the requirement. Now, we only need to find the size of \(T\) that corresponds to \(S\) to solve the problem.
This size can be computed in the method seen in the proof of the existence of \(T\). Naive computation takes \(\mathrm{O}(N)\) time, but one can, say, sort the vertices in BFS order and use a data structure such as a segment tree.
The above is enough to solve the problem, but after some more observation (which we omit), one can solve the problem, without any advanced data structure, by just implementing the following.

  • Pre-compute the number of children of each vertex.
  • The answer to the \(i\)-th query is \(\displaystyle \sum_{j=1}^{M_i}\) (the number of children of \(v_{i,j}\), plus one), but subtract \(2\) from this for each pair of (parent, child). (Maintain \(S_i\) with an associative array to do this fast.)

The solution runs in about \(\mathrm{O}(N + (\sum_i M_i) \log (\sum_i M_i))\) time.

  • Sample implementation (PyPy)
N, Q = map(int, input().split())
par = [-1, -1] + list(map(int, input().split()))
chd = [0] * (N + 1)
for i in range(2, N + 1):
  chd[par[i]] += 1
for _ in range(Q):
  __, *v = map(int, input().split())
  m = {*v}
  print(sum((chd[c] + (-1 if par[c] in m else 1) for c in v)))

posted:
last update: