学习心得 - 数学 - Min-Max 容斥【洛谷 P4707】
续集。
形如如下的式子:
同理:
我不会证,但是我会用举例:我们都知道下列式子成立:
同理,可以合并:
以此类推,我们可以推广到任意长度的
Min-Max 容斥可以推广到任何有关 Min-Max 的东西,比如
扩展 \min-\max 容斥【P4707 重返现世】
式子增加一个组合式子,如下:
例题就拿 P4707 吧,题目大意:有
首先我们 Min-Max 容斥都存在的共性是可期望性。怎么建模成集合?考虑最终的集合
然后
首先我们设
- 不选择第
i 种状态:啥都不会影响(甚至连期望值都没有!)。 - 选择:会影响
|T|-k 的值和\binom{|T|-1}{k-1} 。首先|T|-k 直接正负性更改,然后后面这一项就考虑本质:\binom{|T|}{k-1}=\binom{|T|-1}{k-1}+\binom{|T|-1}{k-2} ,考虑这两个所属的子状态,拆分一下可以得到:f_{i,j,k}=f_{i-1,j-1,k-p_i}-f_{i-1,j,k-p_i} 。
然后最后一个问题:
空间压掉无关紧要的
// #define File
#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define fi first
#define se second
using namespace std;
const ll inf=1e12, P=998244353;
const int N=1e3+10, M=1e4+10;
ll qp(ll a,ll b){
ll res=1;
for(;b;b>>=1,a=(a*a)%P) if(b&1) res=(res*a)%P;
return res;
}
ll f[15][M];
int n,m,kl,p[N];
void solve(){
cin>>n>>kl>>m;
kl=n-kl+1;
for(int i=1;i<=n;i++) cin>>p[i];
for(int j=1;j<=kl;j++) f[j][0]=-1;
for(int i=1;i<=n;i++) for(int j=kl;j>=1;j--)
for(int k=m;k>=p[i];k--) f[j][k]=(f[j][k]+((f[j-1][k-p[i]]-f[j][k-p[i]])%P+P)%P)%P;
ll ans=0;
for(int i=1;i<=m;i++)
ans=(ans+f[kl][i]*qp(i,P-2)%P)%P;
cout<<ans*m%P;
return;
}
int main(){
#ifdef File
freopen("readfile.in","r",stdin);
freopen("readfile.out","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1; // cin>>T;
while(T--) solve();
return 0;
}