Harsh Comments

\(\text{Problem}:\)题目链接

\(\text{Solution}:\)

\(A\) 取子集 \(S\) 时,设 \(Max(S)\) 表示最后被删除的评论 \(A_{k}\)\(B\) 的期望出现次数的最大值,\(Min(S)\) 表示第一个被删除的评论 \(A_{k}\)\(B\) 的期望出现次数的最小值,则我们要求的是 \(Max(S)+n\)

由于期望的线性性,我们可以对每个 \(B_{i}\) 计算出 \(Max(S)\) 并对它们求和。此处需要用到 \(Minmax\) 容斥:

\[\qquad Max(S)=\sum_{T\in S} Min(T)\times (-1)^{\lvert T \rvert-1} \qquad \]

当对每个 \(B_{i}\) 计算时,\(Min(T)\) 非常好算。设 \(W_{T}=\sum_{x\in T} a_{x}\),则 \(Min(T)=\cfrac{B_{i}}{W+B_{i}}\),即 \(B\) 出现在第一个位置的概率。

考虑我们对于所有 \(W_{T}=x\) 求出容斥系数之和,就可以在 \(O(n\sum a_{i}+m\sum a_{i}\log \bmod)\) 的时间复杂度内解决问题。可以用背包实现这一过程。

\(\text{Code}:\)

#include <bits/stdc++.h>
#pragma GCC optimize(3)
#define int long long
#define ri register
#define mk make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define is insert
#define es erase
using namespace std; const int N=110, Mod=998244353;
inline int read()
{
	int s=0, w=1; ri char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
	return s*w;
}
int n,m,a[N],b[N],S,F[N*N],Ans;
inline int ksc(int x,int p) { int res=1; for(;p;p>>=1, x=x*x%Mod) if(p&1) res=res*x%Mod; return res; }
signed main()
{
	n=read(), m=read();
	for(ri int i=1;i<=n;i++) a[i]=read(), S+=a[i];
	for(ri int i=1;i<=m;i++) b[i]=read();
	F[0]=Mod-1;
	for(ri int i=1;i<=n;i++)
	{
		for(ri int j=S;j>=a[i];j--)
		{
			F[j]=(F[j]-F[j-a[i]]+Mod)%Mod;
		}
	}
	for(ri int i=1;i<=m;i++)
	{
		for(ri int j=1;j<=S;j++)
		{
			Ans=(Ans+F[j]*b[i]%Mod*ksc(b[i]+j,Mod-2)%Mod+Mod)%Mod;
		}
	}
	printf("%lld\n",(Ans+n)%Mod);
	return 0;
}
posted @ 2021-03-04 20:39  zkdxl  阅读(321)  评论(2编辑  收藏  举报