题意:
给 定 一 个 集 合 S = { 1 , 2 , . . . , n } , 每 次 删 除 当 前 集 合 中 的 最 小 元 素 , 同 时 再 随 机 删 除 一 个 元 素 , 直 到 ∣ S ∣ = 1 , 求 每 个 元 素 最 后 被 留 下 来 的 概 率 。 给定一个集合S=\lbrace 1,2,...,n\rbrace,每次删除当前集合中的最小元素,同时再随机删除一个元素,直到|S|=1,求每个元素最后被留下来的概率。 给定一个集合S={1,2,...,n},每次删除当前集合中的最小元素,同时再随机删除一个元素,直到∣S∣=1,求每个元素最后被留下来的概率。
n 是 奇 数 , 答 案 对 998244353 取 模 。 n是奇数,答案对998244353取模。 n是奇数,答案对998244353取模。
输入:
T ( 1 ≤ T ≤ 40 ) 组 测 试 数 据 , T(1\le T \le 40)组测试数据, T(1≤T≤40)组测试数据,
每 组 包 括 一 个 正 整 数 n 。 每组包括一个正整数n。 每组包括一个正整数n。
保 证 ∑ n ≤ 5 × 1 0 6 保证\sum n \le 5×10^6 保证∑n≤5×106
输出:
n 个 正 整 数 , 表 示 答 案 。 n个正整数,表示答案。 n个正整数,表示答案。
Sample Input
1
3
Sample Output
0 499122177 499122177
分析:
考 虑 第 i 个 元 素 被 留 下 来 , 前 有 i − 1 个 元 素 , 后 有 n − i 个 元 素 。 考虑第i个元素被留下来,前有i-1个元素,后有n-i个元素。 考虑第i个元素被留下来,前有i−1个元素,后有n−i个元素。
当 且 仅 当 n − i ≤ i − 1 时 , i 才 可 能 被 留 下 。 当且仅当n-i \le i-1时,i才可能被留下。 当且仅当n−i≤i−1时,i才可能被留下。
记 每 次 删 除 最 小 的 元 素 为 操 作 1 , 随 即 删 除 一 个 元 素 为 操 作 2 。 记每次删除最小的元素为操作1,随即删除一个元素为操作2。 记每次删除最小的元素为操作1,随即删除一个元素为操作2。
第 i 个 元 素 后 面 的 元 素 必 是 被 操 作 2 删 除 的 。 第i个元素后面的元素必是被操作2删除的。 第i个元素后面的元素必是被操作2删除的。
而 i 被 留 下 的 情 况 : 而i被留下的情况: 而i被留下的情况:
① 、 一 定 是 i 后 面 的 n − i 个 元 素 与 前 i − 1 个 元 素 中 的 n − i 个 元 素 一 一 对 应 被 删 除 , ①、一定是i后面的n-i个元素与前i-1个元素中的n-i个元素一一对应被删除, ①、一定是i后面的n−i个元素与前i−1个元素中的n−i个元素一一对应被删除,
② 、 接 着 从 前 ( i − 1 ) − ( n − i ) = 2 i − n − 1 个 元 素 中 , 两 两 选 择 删 除 , 直 至 剩 下 第 i 个 元 素 。 ②、接着从前(i-1)-(n-i)=2i-n-1个元素中,两两选择删除,直至剩下第i个元素。 ②、接着从前(i−1)−(n−i)=2i−n−1个元素中,两两选择删除,直至剩下第i个元素。
对 于 情 形 ① , 我 们 先 要 从 前 i − 1 个 元 素 选 择 n − i 个 元 素 一 一 配 对 , 总 的 不 同 选 法 数 量 为 C i − 1 n − i , 对于情形①,我们先要从前i-1个元素选择n-i个元素一一配对,总的不同选法数量为C_{i-1}^{n-i}, 对于情形①,我们先要从前i−1个元素选择n−i个元素一一配对,总的不同选法数量为Ci−1n−i,
由 于 配 对 是 有 顺 序 的 , 对 于 每 一 种 选 法 , 都 对 应 ( n − i ) ! 种 不 同 的 方 案 , 故 ① 的 方 案 总 数 为 C i − 1 n − i × ( n − i ) ! 。 由于配对是有顺序的,对于每一种选法,都对应(n-i)!种不同的方案,故①的方案总数为C_{i-1}^{n-i}×(n-i)!。 由于配对是有顺序的,对于每一种选法,都对应(n−i)!种不同的方案,故①的方案总数为Ci−1n−i×(n−i)!。
对 于 情 形 ② , 此 时 i 为 最 后 一 个 元 素 , 现 从 前 2 i − n − 1 个 元 素 中 两 两 配 对 删 除 , 对于情形②,此时i为最后一个元素,现从前2i-n-1个元素中两两配对删除, 对于情形②,此时i为最后一个元素,现从前2i−n−1个元素中两两配对删除,
故 ② 的 方 案 总 数 为 故②的方案总数为 故②的方案总数为
C 2 i − n − 1 2 × C 2 i − n − 3 2 × . . . × C 2 2 = ( 2 i − n − 1 ) ! ( 2 i − n − 1 − 2 ) ! ⋅ 2 ! × ( 2 i − n − 3 ) ! ( 2 i − n − 3 − 2 ) ! ⋅ 2 ! × . . . × 1 = ( 2 i − n − 1 ) ! 2 ! 2 i − n − 1 2 C_{2i-n-1}^2×C_{2i-n-3}^2×...×C_{2}^2=\frac{(2i-n-1)!}{(2i-n-1-2)!·2!}×\frac{(2i-n-3)!}{(2i-n-3-2)!·2!}×...×1=\frac{(2i-n-1)!}{2!^{\frac{2i-n-1}{2}}} C2i−n−12×C2i−n−32×...×C22=(2i−n−1−2)!⋅2!(2i−n−1)!×(2i−n−3−2)!⋅2!(2i−n−3)!×...×1=2!22i−n−1(2i−n−1)!
注意: 选 择 这 2 i − n − 1 2 对 , 顺 序 是 固 定 的 。 例 如 ( 1 , 3 ) 和 ( 2 , 4 ) , 必 然 是 先 删 除 ( 1 , 3 ) 再 删 除 ( 2 , 4 ) , 选择这\frac{2i-n-1}{2}对,顺序是固定的。例如(1,3)和(2,4),必然是先删除(1,3)再删除(2,4), 选择这22i−n−1对,顺序是固定的。例如(1,3)和(2,4),必然是先删除(1,3)再删除(2,4),
这 个 顺 序 是 固 定 的 , 因 此 最 后 我 们 还 要 考 虑 这 2 i − n − 1 2 对 排 列 顺 序 的 影 响 , 故 将 上 式 再 除 ( 2 i − n − 1 2 ) ! 。 \qquad\ \ 这个顺序是固定的,因此最后我们还要考虑这\frac{2i-n-1}{2}对排列顺序的影响,故将上式再除(\frac{2i-n-1}{2})!。 这个顺序是固定的,因此最后我们还要考虑这22i−n−1对排列顺序的影响,故将上式再除(22i−n−1)!。
综 上 , 元 素 i 被 留 下 来 的 方 案 总 数 为 : 综上,元素i被留下来的方案总数为: 综上,元素i被留下来的方案总数为:
c n t [ i ] = C i − 1 n − i × ( n − i ) ! × ( 2 i − n − 1 ) ! 2 ! 2 i − n − 1 2 / ( 2 i − n − 1 2 ) ! cnt[i]=C_{i-1}^{n-i}×(n-i)!×\frac{(2i-n-1)!}{2!^{\frac{2i-n-1}{2}}}\ /\ (\frac{2i-n-1}{2})! cnt[i]=Ci−1n−i×(n−i)!×2!22i−n−1(2i−n−1)! / (22i−n−1)!
方 案 总 数 为 : s u m = ∑ i = 1 n c n t [ i ] 方案总数为:sum=\sum_{i=1}^ncnt[i] 方案总数为:sum=∑i=1ncnt[i]
则 第 i 数 留 下 的 概 率 为 : 则第i数留下的概率为: 则第i数留下的概率为: p [ i ] = c n t [ i ] s u m p[i]=\frac{cnt[i]}{sum} p[i]=sumcnt[i]
注意: 情 况 ② 仅 在 ( i − 1 ) ≥ ( n − i ) 时 才 会 被 计 算 , 避 免 数 组 越 界 。 情况②仅在(i-1)\ge(n-i)时才会被计算,避免数组越界。 情况②仅在(i−1)≥(n−i)时才会被计算,避免数组越界。
代码:
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int N=5e6, mod=998244353;
int T, n;
int fac[N+10], inv[N+10], inv_fac2[N+10];
int cnt[N+10];
int quick_pow(int a,int b, int mod)
{
int res=1;
while(b)
{
if(b&1) res=(ll)res*a%mod;
a=(ll)a*a%mod;
b>>=1;
}
return res;
}
void Init()
{
fac[0]=1;
for(int i=1;i<=N;i++) fac[i]=(ll)fac[i-1]*i%mod;
inv[N]=quick_pow(fac[N],mod-2,mod);
for(int i=N-1;i>=0;i--) inv[i]=(ll)inv[i+1]*(i+1)%mod;
inv_fac2[0]=1;
inv_fac2[1]=quick_pow(2,mod-2,mod);
for(int i=2;i<=N;i++) inv_fac2[i]=(ll)inv_fac2[i-1]*inv_fac2[1]%mod;
}
int C(int n,int m)
{
if(n<m) return 0;
return (ll)fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
Init();
cin>>T;
while(T--)
{
scanf("%d",&n);
int sum=0;
for(int i=1;i<=n/2;i++) cnt[i]=0;
for(int i=n/2+1;i<=n;i++)
{
cnt[i]=(ll)C(i-1,n-i)*fac[n-i]%mod;
if(i-1>n-i) cnt[i]=(ll)cnt[i]*fac[2*i-n-1]%mod*inv[(2*i-n-1)/2]%mod*inv_fac2[(2*i-n-1)/2]%mod;
sum=(sum+cnt[i])%mod;
}
sum=quick_pow(sum,mod-2,mod);
for(int i=1;i<=n;i++) {printf("%d",(ll)cnt[i]*sum%mod);if(i!=n) printf(" ");}
puts("");
}
return 0;
}