垫底了。
A. 吊灯
如果这棵树能够分割成 \(n/d\) 个大小为 \(d\) 的连通块,那么一定有 \(n/d\) 个子树的 \(\mathrm{size}\) 是 \(d\) 的倍数。
证明的话,称子树 \(\mathrm{size}\) 是 \(d\) 的倍数的点为关键点,那么根一定是关键点;其次,\(n\) 减去树中的所有极大关键点(即祖先中除了根以外都不是关键点)的 \(\mathrm{size}\) 一定是 \(d\) 的倍数;又因为有 \(n/d\) 个关键点,那么这个数恰好为 \(d\)。
所以 \(\mathcal O(\sqrt n)\) 枚举约数即可。
比较卡常,不要显式的建树 dfs。
B. 小Z爱求和
在一般的情况下,一个数 \(x\) 产生贡献的区间为 \([l,r]\) 内大于等于 \(x\) 的数恰好有 \(k\) 个的区间。
考虑先按照 \(a_i\) 排序,然后维护位置的集合,从小到大枚举 \(a_i\),在小于等于 \(a_i\) 的位置集合中找到所有长为 \(k\) 且包含 \(i\) 的连续段统计。
直接用 std::set<>
做是 \(\mathcal O(nk\log n)\) 的,倒着用链表可以降为 \(\mathcal O(nk)\)。
C. 关押罪犯
子集 DP。
D. 小P走迷宫
容斥。