组合数学--Set1 hdu-6825

Problem Description

You are given a set S = 1.. n S={1..n} 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 S S. Then randomly delete another element from S S S.

For each i ∈ [ 1 , n ] i\in[1,n] i[1,n], determine the probability of i i i being left in the S S S.

It can be shown that the answers can be represented by P Q \frac{P}{Q} QP, where P P P and Q Q Q are coprime integers, and print the value of P × Q − 1 P×Q^{-1} P×Q1 m o d mod mod 998244353 998244353 998244353.

思路

  • 对于每次数据 n n n,设 n u m = n 2 num=\frac{n}{2} num=2n, 可知 ∀ i ∈ [ 1 , n u m ] \forall i\in[1,num] i[1,num]的期望值是0
  • ∀ i ∈ [ n u m + 1 , n ] \forall i\in[num+1,n] i[num+1,n],每次最后剩余他的次数 c n t [ i ] cnt[i] cnt[i]
    1. 首先对于 i i i 后面的 n − i n-i ni 个数,需要前面的 i − 1 i-1 i1 个数来达到消去的效果,所以这里的总次数是
      C i − 1 n − i ∗ ( n − i ) ! C_{i-1}^{n-i}*(n-i)! Ci1ni(ni)!
    2. 使后面 n − i n-i ni 个数消去后, i i i 前面还剩余 ( i − 1 ) − ( n − i ) = 2 i − n − 1 (i-1)-(n-i)=2i-n-1 (i1)(ni)=2in1 个数,而这里两两匹配的总个数为
      ∏ j = 1 2 i − n − 1 j , ( j ∈ 2 k + 1 ∣ k ∈ N ) \prod_{j=1}^{2i-n-1}j,(j\in2k+1|k\in N) j=12in1j,(j2k+1kN)
    3. 综上可得 c n t [ i ] = C i − 1 n − i ∗ ( n − i ) ! ∗ ∏ j = 1 2 i − n − 1 j , ( j ∈ 2 k + 1 ∣ k ∈ N ) cnt[i]=C_{i-1}^{n-i}*(n-i)!*\prod_{j=1}^{2i-n-1}j,(j\in2k+1|k\in N) cnt[i]=Ci1ni(ni)!j=12in1j,(j2k+1kN),即 j j j 为奇数
  • 对于每个 n n n,总数 s u m = ∑ i = 1 i = n c n t [ i ] sum=\sum_{i=1}^{i=n}cnt[i] sum=i=1i=ncnt[i],可知
    s u m 1 = 1 = 2 0 ∗ 0 ! sum_1=1=2^0*0! sum1=1=200! , ( 0 ! = 1 ) (0!=1) (0!=1)
    s u m 3 = 2 = 2 1 ∗ 1 ! sum_3=2=2^1*1! sum3=2=211!
    s u m 5 = 8 = 2 2 ∗ 2 ! sum_5=8=2^2*2! sum5=8=222!
    s u m 7 = 48 = 2 3 ∗ 3 ! sum_7=48=2^3*3! sum7=48=233!
    s u m 9 = 384 = 2 4 ∗ 4 ! sum_9=384=2^4*4! sum9=384=244!
    所以可得知 n u m = n / 2 , s u m n = 2 n u m ∗ ( n u m ) ! num=n/2,sum_n=2^{num}*(num)! num=n/2,sumn=2num(num)!
  • 所以总的期望值 p [ i ] = C i − 1 n − i ∗ ( n − i ) ! ∗ ∏ j = 1 2 i − n − 1 j 2 n u m ∗ ( n u m ) ! , ( j ∈ 2 k + 1 ∣ k ∈ N ) p[i]=\frac{C_{i-1}^{n-i}*(n-i)!*\prod_{j=1}^{2i-n-1}j}{2^{num}*(num)!},(j\in2k+1|k\in N) p[i]=2num(num)!Ci1ni(ni)!j=12in1j(j2k+1kN)
  • 下面的代码中 f a c [ i ] = i ! , i f a c [ i ] = f a c − 1 [ i ] , m f a c [ 2 i − n − 1 2 ] = ∏ j = 1 2 i − n − 1 j fac[i]=i!,ifac[i]=fac^{-1}[i],mfac[\frac{2i-n-1}{2}]=\prod_{j=1}^{2i-n-1}j fac[i]=i!,ifac[i]=fac1[i],mfac[22in1]=j=12in1j
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template <typename T>
inline void read(T &x)
{
    
    
    int tmp = 1;char c = getchar();x = 0;
    while (c > '9' || c < '0'){
    
    if (c == '-')tmp = -1;c = getchar();}
    while (c >= '0' && c <= '9'){
    
    x = x * 10 + c - '0';c = getchar();}
    x *= tmp;
}
const int inf=0x3f3f3f3f;
const int mod=998244353;
const int N=5e6+10;
const int M=1e7+10;
ll fp(ll x,ll y){
    
    
	ll ans=1;
	while(y){
    
    
		if(y&1) ans=ans*x%mod;
		x=x*x%mod;
		y>>=1;
	}
	return ans;
}
ll fac[N],ifac[N],mfac[N];
inline ll C(int n,int k){
    
    
	return fac[n]*ifac[n-k]%mod*ifac[k]%mod;
}
int main(){
    
    
	ios::sync_with_stdio(false);cin.tie(nullptr); cout.tie(nullptr);
	fac[0]=1;
	for(int i=1;i<=5e6;++i) fac[i]=fac[i-1]*i%mod;
	ifac[N-10]=fp(fac[N-10],mod-2);
	for(int i=5e6-1;i>=0;--i) ifac[i]=ifac[i+1]*(i+1)%mod;
	mfac[0]=mfac[1]=1;
	for(int i=1;i<=3e6;++i) mfac[i+1]=mfac[i]*(i<<1|1)%mod;
	int T;read(T);
	while(T--){
    
    
		int n;read(n);
		if(n==1){
    
    
			puts("1");
			continue;
		}
		int num=n/2;
		ll down=fp(2,num)*fac[num]%mod;
		down=fp(down,mod-2);
		for(int i=1;i<=num;++i){
    
    
			if(i==1) printf("0");
			else printf(" 0");
		}
		for(int i=num+1;i<=n;++i){
    
    
			printf(" %lld",C(i-1,n-i)*fac[n-i]%mod*mfac[(2*i-n-1)/2]%mod*down%mod);
		}
		puts("");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bloom_er/article/details/107997418