题目
正解
听Cold_Chair说这是从LOJ2541改过来的题。
原本还是有组合意义的,然后毒瘤的出题人就强行将这个组合意义隐藏了起来。
这题要求。
改成这样看看有什么组合意义:
考虑从往枚举,可以看做一个选数字然后删掉的过程。某个数字被选到的概率就是它的权值占总和的比例。
上面的那条式子中,是枚举了排列,然后依次删去的概率。
如果把提出来,由于前面有个求和,这就可以看成:对于每个,它最后一个被删去的概率是多少。
于是相当于这样:。
这里的指的是一开始给出的值而不是排列中的位置。
那么考虑如何计算这个东西。
(为了方便计算,记最后一个被删去的值为)
发现这个最后一个被删去的概率不太好算,但是第一个被删去的概率好算。
设有某个集合,它里面的所有数都是在后面删去,那么概率是
相当于在这些数中,直接将选出来删了。
简单容斥一下:
对于每个,枚举,然后计算贡献。
对于,它的生成函数就是(变量重名用代替)。
乘起来,对于每个除去自己的贡献即可。
从转化过后的问题变成原问题只需要将那些多了的因数除去即可。
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 210
#define M 262144
#define ll long long
#define mo 998244353
int n;
int w[N];
int inv[M];
int F[M],t[M],G[M];
int main(){
// freopen("in.txt","r",stdin);
freopen("restaurant.in","r",stdin);
freopen("restaurant.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&w[i]);
int mx=0;
F[0]=1;
for (int i=1;i<=n;++i){
for (int j=mx;j>=0;--j)
F[j+w[i]]=(F[j+w[i]]-F[j]+mo)%mo;
mx+=w[i];
}
inv[0]=0,inv[1]=1;
for (int i=2;i<=mx;++i)
inv[i]=(ll)(mo-mo/i)*inv[mo%i]%mo;
ll pro=1;
for (int i=1;i<=n;++i)
pro=pro*inv[w[i]]%mo;
ll ans=0;
for (int i=1;i<=n;++i){
memcpy(t,F,sizeof(int)*(mx+1));
memset(G,0,sizeof(int)*(mx+1));
for (int j=mx;j>=w[i];--j){
(t[j-w[i]]+=t[j])%=mo;
(G[j-w[i]]+=mo-t[j])%=mo;
t[j]=0;
}
int mxi=mx-w[i];
ll s=0;
for (int j=0;j<=mxi;++j)
(s+=(ll)w[i]*inv[j+w[i]]%mo*G[j])%=mo;
s=(ll)s*(pro*w[i]%mo)%mo;
ans+=s;
}
ans%=mo;
printf("%lld\n",ans);
return 0;
}
总结
据说这是一道没有见过就做不出来的组合意义题……