(A)
枚举一个 (K)。 那么每个联通块的点数就是 (frac{N}{K + 1})。
那么有解当且仅当子树大小为 (frac{N}{K + 1}) 的倍数的数量恰好为 (K + 1) 个。
时间复杂度 : (O(N))。
(B)
首先考虑每个点走到什么时候会到原点 , 可以用 (std::map) 维护。
设 (dp_{i}) 表示从 (i) 走到 (N) 的位移。 直接转移即可。
时间复杂度 : (O(NlogN))
(C)
一个基本事实是 :
(A oplus B + B oplus C geq A oplus C) ((oplus) 可以取 (OR) 或 (XOR))
那么对于这两种操作直接维护前缀和即可。
对于 (AND) 的情况 , 枚举一个最高位 (i) , 那么必然选取有这个位的最深的祖先节点进行转移。 这样只需要在 (DFS) 时维护一个 (last) 数组即可。
时间复杂度 : (O(NlogV))
(D)
首先用整数分拆算出 (i) 分 (j) 份的方案。
考虑每个元素的贡献。枚举这个元素出现次数 , 那么其贡献是 (K ^ {M}F_{N - ij , K - j})。
时间复杂度 : (O(N ^ 2))