#include<bits/stdc++.h>
using namespace std;
using VI = vector<int>;
using ll = long long;
using PII = pair <int , int>;
const int N = 1e6;
const int mod = 998244353;
int n;
int x;
int t[200010];
ll s[2000010] ;
//第 i 首 歌曲结束在 第 j 秒的概率
//dp[i][j] = dp[k][j-t[k]];
//dp[i][j] -> dp[k][j+t[k]];
//dp[k][j+t[k]] = s[j] 求和
//动态维护第 j 秒刚好有一个歌曲结束的概率s[j]
ll power(ll x,ll p,ll m){
ll res = 1;
while(p){
if(p%2 == 1){
res *= x;
res %= m;
}
p /= 2;
x = x * x % m;
}
return res;
}
int main(){
cin>>n>>x;
ll k = power(n,mod - 2 , mod);
for(int i = 1 ; i <= n ; i++) cin>>t[i];
s[0] = 1;
for(int j = 1 ; j <= x ; j++){
for(int i = 1 ; i <= n ; i++){
if(j - t[i] >= 0)s[j] += s[j-t[i]];
s[j] %= mod;
}
s[j] = (s[j] * k) % mod;
}
ll res = 0;
for(int i = max(x + 1 - t[1],0) ; i <= x ; i++){
res = (res + s[i] * k % mod) % mod;
//res %= mod;
}
cout<<res;
}
本质上就是一个枚举子集的问题 ,无限背包的思想属于是
s[ i ] 表示第 i 秒刚好有一首曲子结束的概率
s[ i ] += s[ i - t[k] ]; (i - t[k] >= 0)
然后就是求逆元的问题
a/b 关于p的逆元 (a * x)% p 其实x就是b的逆元