2020杭电多校第五场 Set1(组合数学,概率)

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 i1个数,后面有 n − i n-i ni个数。
要求剩下的是 i i i,则需要满足 i − 1 ≥ n − i i-1≥n-i i1ni。则后面 n − i n-i ni个数肯定是和前面的数一一对应被删掉。前面剩下 2 ∗ i − n − 1 2*i-n-1 2in1个数最后两两配对被删掉。

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]=(nii1)(ni)!(2!)2(2in1)2(2in1)!(2in1)!

最后要除这个 ( 2 ∗ i − n − 1 ) 2 ! \frac{(2*i-n-1)}{2}! 2(2in1)!,是因为选出来的 ( 2 ∗ i − 1 − n ) 2 \frac{(2*i-1-n)}{2} 2(2i1n)个二元组中,第一个数字必须递增,所以第一个数字仍以排列的情况要除去。

#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;
}

你可能感兴趣的:(#,组合数,#,概率,#,其他比赛题目)