題目
正解
聽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;
}
總結
據說這是一道沒有見過就做不出來的組合意義題……