6699. 【2020.06.06省选模拟】这钵和餐厅配合的不是很好

题目


正解

听Cold_Chair说这是从LOJ2541改过来的题。
原本还是有组合意义的,然后毒瘤的出题人就强行将这个组合意义隐藏了起来。

这题要求xii=2n1j=1ixj\sum_{x_i}\prod_{i=2}^n {\frac{1}{\sum_{j=1}^ix_j}}
改成这样看看有什么组合意义:xii=1nxij=1ixj\sum_{x_i}\prod_{i=1}^n {\frac{x_i}{\sum_{j=1}^ix_j}}
考虑iinn11枚举,可以看做一个选数字然后删掉的过程。某个数字被选到的概率就是它的权值占总和的比例。
上面的那条式子中,是枚举了排列,然后依次删去xn,xn1,...,x2,x1x_n,x_{n-1},...,x_2,x_1的概率。
如果把x1x_1提出来,由于前面有个求和,这就可以看成:对于每个x1x_1,它最后一个被删去的概率是多少。
于是相当于这样:ixi\sum_{i}x_i最后一个被删去的概率
这里的xix_i指的是一开始给出的值而不是排列中的位置。

那么考虑如何计算这个东西。
(为了方便计算,记最后一个被删去的值为x1x_1
发现这个最后一个被删去的概率不太好算,但是第一个被删去的概率好算。
设有某个集合SS,它里面的所有数都是在x1x_1后面删去,那么概率是x1(xi)+x1\frac{x_1}{(\sum x_i)+x_1}
相当于在这些数中,直接将x1x_1选出来删了。
简单容斥一下:S(1)Sx1(xi)+x1\sum_S (-1)^{|S|}\frac{x_1}{(\sum x_i)+x_1}
对于每个x1x_1,枚举xi\sum x_i,然后计算贡献。
对于xix_i,它的生成函数就是(1yxi)(1-y^{x_i})(变量重名用yy代替)。
乘起来,对于每个x1x_1除去自己的贡献即可。

从转化过后的问题变成原问题只需要将那些多了的因数除去即可。

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

总结

据说这是一道没有见过就做不出来的组合意义题……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章