cube
考虑 (n) 维基础图形, 它的所有点集可以用向量 ((0/1,0/1,dots,0/1)) 来表示.
考虑用它来表示线段, 相当于在原来的向量里任取一个位置出来, 这个位置取遍 (0/1) 来表示两个点构成的线段, 其他位置的选择代表着不同位置的线段.
考虑用它来表示正方形, 相当于在原来的向量里任取两个位置出来, 这两个位置取遍 (0/1) 来表示两个线段集构成的面, 其他位置的选择代表着不同位置的正方形.
那么拓展到 (m) 维, 相当于取 (m) 个出来作为基础向量, 其他部分任取代表不同的元素. 那么可以发现方案数就是 (inom{n}{m}2^{n-m}).
或者通过打表得出结论.
代码
divide
首先有个很显然的 DP: (f[i][j]) 表示前 (i) 个数, 选了 (j) 个到 (A) 集合的最大值, 那么如果能够快速算出一个数放入 (A), (B) 的贡献就做完了.
发现贡献不好算, 一般思路是用数据结构维护. 但是注意到答案和 (w_i) 的顺序是无关的, 于是可以将 (w_i) 重新排序使得这个贡献容易计算.
可以构造一个排列, 使得 (forall i>1), 或者 (forall 1le j<i,w_j+w_ige m), 或者(forall 1le j<i,w_j+w_i< m). 这样贡献就很好算了.
幸运的是, 这样的排列是可以构造出来的. 考虑将 (w_i) 排序, 考虑 (w_1) 和 (w_n) 的关系, 然后可以将其转化成一个 规模为 (n-1) 的子问题.
代码
magic
想到容斥, 设 (f[i]) 表示至少 (i) 个魔术对的方案数, 然后通过二项式反演得出答案.
然后将一个魔术对看成将这个颜色的球减少 1, 假设最终每个颜色的球有 (a_i) 个, 那么答案就是 (frac{(sum a_i)!}{prod a_i!}).
发现每个颜色是独立的. 于是考虑其生成函数 (F(x)=sum_{j=1}^{a_i}{frac{inom{a_i-1}{j-1}}{j!}x^j}). 答案就是所有 (F(x)) 乘积的系数(最后不要忘记乘 (i!)).
注意到 (nle 10^5), 那么直接分治 NTT 解决就好了.
代码