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

總結

據說這是一道沒有見過就做不出來的組合意義題……

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