HDU6825:Set1——题解

http://acm.hdu.edu.cn/showproblem.php?pid=6825

给你一个集合$S=\{1..n\}$。保证 $n$ 是奇数。必须执行以下操作,直到集合中只有一个元素:

首先删除 $S$ 的最小元素,然后从 $S$ 中随机删除另一个元素。

对于每个 $i∈[1,n]$ ,确定 $i$ 留在 $S$ 中的概率。

emm题解u1s1很好看懂,但打的时候我反正是蒙蔽的,然后就打表做的。打表也不难,讲讲怎么打的表。

设 $f[i][j]$ 为有 $j$ 个元素的集合里第i个元素存活概率。

显然 $f[i][j]=((j-i)*f[i-1][j-2]+(i-2)*f[i-2][j-2])/(j-1)$ 。

然后意识到除 $j-1$ 这块打表用不到,于是扔掉 $j-1$ 开始打表。

然后发现惊天大秘密(

当 $n$ 为 $1,3,5,7,9$ 时,有:

1
0 1 1
0 0 2 3 3
0 0 0 6 12 15 15
0 0 0 0 24 60 90 105 105

首先就是每行最后两个数相同,且都为 $(n-2)!!$ 。

其次通过表可以发现 $f[i][j]=f[i-1][j-2]*(i-1)$ ,并且如果这个式子不断地递归下去的话,要么为 $0$ ,要么得到的式子里的 $f$ 的两维的数是一样的。

于是对于给定的询问 $n$ 个元素当中第 $x$ 个元素存活概率,有如下算法:

1.如果 $2*x-n-1<0$ ,则答案为 $0$ 。

2.否则,答案为 $(x-1)!/(2*x-n-1)!*f[2*x-n][2*x-n]$ ,而 $f[2*x-n][2*x-n]=(2*x-n-2)!!$ (当然你需要为 $2*x-n=1$ 进行特判)

最后的答案不要忘记把我们之前抛掉的除 $j-1$ 加回来,其实利用一开始的dp式子可以知道实际上答案只需要多除一个 $(n-1)!!$ 即可。

#include<bits/stdc++.h>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
const ll p=998244353;
const int N=5e6+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
void write(ll x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
ll inv[N],JJ[N],J[N];
inline ll getequ(int x){
    if(x==1)return 1;
    return JJ[x-2];
}
ll qpow(ll k,int n){
    ll res=1;
    while(n){
        if(n&1)res=res*k%p;
        k=k*k%p;n>>=1;
    }
    return res;
}
ll sol(int x,int n){
    int del=n-x;
    if(x-del-1<0)return 0;
    ll ans=J[x-1]*qpow(J[x-del-1],p-2)%p;
    return ans*getequ(x-del)%p;
}
void init(){
    inv[0]=inv[1]=1;J[0]=J[1]=JJ[1]=1;
    for(int i=2;i<N;i++){
        J[i]=J[i-1]*i%p;
        inv[i]=(p-p/i)*inv[p%i]%p;
    }
    for(int i=2;i<N;i+=2){
        inv[i]=inv[i]*inv[i-2]%p;
    }
    for(int i=3;i<N;i+=2){
        JJ[i]=JJ[i-2]*i%p;
    }
}
int main(){
    init();
    int T=read();
    while(T--){
        int n=read();
        for(int i=1;i<=n;i++){
            write(sol(i,n)*inv[n-1]%p);
            if(i!=n)space;
        }
        enter;
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2020-08-04 17:50  luyouqi233  阅读(350)  评论(0编辑  收藏  举报