题目描述
Alien 的战舰不能搭载太多人,他需要在战舰上安装一些乘客客舱。
可以安装的客舱有 (2p) 个型号,分别能搭载 (1) 至 (2p) 个乘客,每种型号有且仅有一个。
为了方便搭载的过程,Alien 希望恰好安装 (p) 个乘客客舱,且可搭载的乘客数量和必须为 (p) 的倍数。
Alien 想知道共有几种方案?
输入格式
本题有多组数据。
第一行为数据组数 (n);
接下来 (n) 行每行包含一个 奇质数 (p)。
输出格式
对于每组数据输出一行,表示方案数。
数据范围
测试时间限制 (500 mathrm{ms}),空间限制 (64 mathrm{MiB})。
- 对于 (30\%) 的数据,(nle 10),(ple 10);
- 对于 (70\%) 的数据,(nle 100),(ple 30);
- 对于 (100\%) 的数据 (0le nle 100),(3le ple 1000)。
分析
这题一看就是个结论题。怎么推呢?
首先,我们将其抽象成一个数学问题:
给定集合 (S=left{k|kin mathbb{N}^{+},1le kle 2p ight})。
求出 (|T|),其中 (T=left{S^prime|S^primesubseteq S,sumlimits_{xin S^prime}xmod{p}=0 ight})
嗯?怎么越来越不明所以了?
接下来,我们就考虑一下怎么解决。
首先,注意到前面 (p) 个数与后面 (p) 个数等价。
又 (forall Sin T exists\, S_1,S_2 S_1cap S_2=varnothing, S_1subseteq {k|kin mathbb{N}^{+},1le kle p}, S_2subseteq {k|kin mathbb{N}^{+},p+1le kle 2p}, S_1cup S_2=S)
即给定 (S_1),(S_2),能得到确定的 (S)。
接下来考虑如何搭配 (S_1) 和 (S_2)。
考虑给定 (S_1),有多少个 (S_2) 与其配对。
由于能够影响的只有余数,下面规定 (f_i) 为 (S^primesubseteq {k|kin mathbb{N}^+, 1le kle p},sumlimits_{xin S^prime}xmod{p}=i) 的个数。
发现单独考虑并不容易,我们试图整体考虑。
注意到选择 (f_i) 时,选择的个数不会是 (p) 的倍数(全选和不选除外)。如果对于选的每一个数加一,那么就会产生另一种选择方案,其和的余数与原方案不同。
这样进行 (p-1) 次,我们就能得到一个关于 (p) 的最小剩余系。其中只有一个方案是合法的。
也就是说,除去全选和不选的方案,剩下的所有方案是平均分的。
于是,答案实际上就是 (dfrac{dbinom{2p}{p}-2}{p}+2)
最后再套上个高精度就能解决问题了。
Code
后来,我还是放弃了高精度……实在是太烦了。
#include <cstdio>
using namespace std;
typedef long long ll;
int main()
{
int cas, n;
ll ans;
scanf("%d", &cas);
while (cas--)
{
scanf("%d", &n);
ans = 1;
for (int i = n + 1; i <= 2 * n; i++)
ans *= i;
for (int i = 1; i <= n; i++)
ans /= i;
printf("%d
", (ans - 2) / n + 2);
}
return 0;
}