cube
考虑 \(n\) 维基础图形, 它的所有点集可以用向量 \((0/1,0/1,\dots,0/1)\) 来表示.
考虑用它来表示线段, 相当于在原来的向量里任取一个位置出来, 这个位置取遍 \(0/1\) 来表示两个点构成的线段, 其他位置的选择代表着不同位置的线段.
考虑用它来表示正方形, 相当于在原来的向量里任取两个位置出来, 这个位置取遍 \(0/1\) 来表示两个线段集构成的面, 其他位置的选择代表着不同位置的正方形.
那么拓展到 \(m\) 维, 相当于取 \(m\) 个出来作为基础向量, 其他部分任取代表不同的元素. 那么可以发现方案数就是 \(\binom{n}{m}2^{n-m}\).或者通过打表得出结论.
代码
divide
首先有个很显然的 DP: \(f[i][j]\) 表示前 \(i\) 个数, 选了 \(j\) 个到 \(A\) 集合的最大值, 那么如果能够快速算出一个数放入 \(A\), \(B\) 的贡献就做完了.
发现贡献不好算, 一般思路是用数据结构维护. 但是注意到答案和 \(w_i\) 的顺序是无关的, 于是可以将 \(w_i\) 重新排序使得这个贡献容易计算.
可以构造一个排列, 使得 \(\forall i>1\), 或者 \(\forall 1\le j<i,w_j+w_i\ge m\), 或者\(\forall 1\le 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{\binom{a_i-1}{j-1}}{j!}x^j}\). 答案就是所有 \(F(x)\) 乘积的系数(最后不要忘记乘 \(i!\)).
注意到 \(n\le 10^5\), 那么直接分治 NTT 解决就好了.
代码