Problem Description
You are given a set S={1…n}. It guarantees that n is odd. You have to do the following operations until there is only 1 element in the set:
Firstly, delete the smallest element of S. Then randomly delete another element from S.
For each i∈[1,n], determine the probability of i being left in the S.
It can be shown that the answers can be represented by PQ, where P and Q are coprime integers, and print the value of P×Q−1 mod 998244353.
Input
The first line containing the only integer T(T∈[1,40]) denoting the number of test cases.
For each test case:
The first line contains a integer n .
It guarantees that: ∑n∈[1,5×106].
Output
For each test case, you should output n integers, i-th of them means the probability of i being left in the S.
Sample Input
1
3
Sample Output
0 499122177 499122177
Source
2020 Multi-University Training Contest 5
这场全是推公式题,恶心心
感谢arc3102大佬指出一些错误
题意:
n个数,每次选一个最小的数扔掉,再仍以选择一个数扔掉。求最后剩下的数是i的概率。
思路:
假设剩下的数字是 i i i,那么前面有 i − 1 i-1 i−1个数,后面有 n − i n-i n−i个数。
要求剩下的是 i i i,则需要满足 i − 1 ≥ n − i i-1≥n-i i−1≥n−i。则后面 n − i n-i n−i个数肯定是和前面的数一一对应被删掉。前面剩下 2 ∗ i − n − 1 2*i-n-1 2∗i−n−1个数最后两两配对被删掉。
则 c n t [ i ] = ( i − 1 n − i ) ∗ ( n − i ) ! ∗ ( 2 ∗ i − n − 1 ) ! ( 2 ! ) ( 2 ∗ i − n − 1 ) 2 ∗ ( 2 ∗ i − n − 1 ) 2 ! cnt[i]=\tbinom{i-1}{n-i}*(n-i)!*\frac{(2*i-n-1)!}{(2!)^{\frac{(2*i-n-1)}{2}}*\frac{(2*i-n-1)}{2}!} cnt[i]=(n−ii−1)∗(n−i)!∗(2!)2(2∗i−n−1)∗2(2∗i−n−1)!(2∗i−n−1)!
最后要除这个 ( 2 ∗ i − n − 1 ) 2 ! \frac{(2*i-n-1)}{2}! 2(2∗i−n−1)!,是因为选出来的 ( 2 ∗ i − 1 − n ) 2 \frac{(2*i-1-n)}{2} 2(2∗i−1−n)个二元组中,第一个数字必须递增,所以第一个数字仍以排列的情况要除去。
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mod = 998244353;
const int maxn = 5e6 + 7;
ll fac[maxn],inv[maxn],INV[maxn];
ll qpow(ll x,ll n) {
ll res = 1;
while(n) {
if(n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
void init() {
fac[0] = inv[0] = INV[0] = 1;
for(int i = 1;i < maxn;i++) {
fac[i] = fac[i - 1] * i % mod;
inv[i] = inv[i - 1] * qpow(i,mod - 2) % mod;
INV[i] = INV[i - 1] * qpow(2,mod - 2) % mod;
}
}
ll C(ll n,ll m) {
if(n < m || m < 0) return 0;
return fac[n] * inv[n - m] % mod * inv[m] % mod;
}
int main() {
init();
int T;scanf("%d",&T);
while(T--) {
int n;scanf("%d",&n);
ll sum = 0;
for(int i = (n + 1) / 2;i <= n;i++) {
ll num = C(i - 1,n - i) * fac[n - i] % mod * fac[2 * i - n - 1] % mod * INV[(2 * i - n - 1) / 2] % mod * inv[(2 * i - n - 1) / 2] % mod;
sum += num;
sum %= mod;
}
sum = qpow(sum,mod - 2);
for(int i = 1;i <= n;i++) {
if(i < (n + 1) / 2) printf("0 ");
else {
ll num = C(i - 1,n - i) * fac[n - i] % mod * fac[2 * i - n - 1] % mod * INV[(2 * i - n - 1) / 2] % mod * inv[(2 * i - n - 1) / 2] % mod;
printf("%lld",num * sum % mod);
if(i != n) printf(" ");
}
}
printf("\n");
}
return 0;
}