Min-max 容斥与 kth 容斥

期望的线性性:

\[E(x+y)=E(x)+E(y) \]

证明:

\[E(x+y)=\sum_i \sum_j(i+j)*P(i=x,j=y) \]

\[=\sum_i\sum_ji*P(i=x,j=y)+\sum_i\sum_jj*P(i=x,j=y) \]

\[=\sum_ii*P(i=x)+\sum_jj*P(j=y) \]

\[=E(x)+E(y) \]


Min - Max 容斥:

我们现在有一个全集 \(U= \lbrace{a_1,a_2,a_3,...,a_n}\rbrace\)

我们设:

\[\begin{cases} {\max(S)=\max\limits_{a_i∈S}a_i}\\ {\min(S)=\min\limits_{a_i∈S}a_i}\\ \end{cases} \]

有:

\[\begin{cases} \max(S)=\sum_{T \in S}\limits(-1)^{|T|-1}\min(T)\\ \min(S)=\sum_{T \in S}\limits(-1)^{|T|-1}\max(T)\\ \end{cases} \]

二项式反演证明:

我们想构造一个函数 \(f\) ,使得:

\[\max(S)=\sum_{T \in S}\limits f(T)\min(T) \]

然后依然考虑一个元素排序后在哪些集合产生贡献

假设某个元素从小到大后排在第 \(x\) 位(集
合大小为 \(n\)),那么它的贡献就是:

\[[x = n] *val=\sum_{i=0}^{n-x}\left(\begin{array}{c}n-x\\ i\end{array}\right)f(i+1)*val \]

\[[x = n]=\sum_{i=0}^{n-x}\left(\begin{array}{c}n-x\\ i\end{array}\right)f(i+1) \]

变换一下:

\[[n-x = 0]=\sum_{i=0}^{n-x}\left(\begin{array}{c}n-x\\ i\end{array}\right)f(i+1) \]

\[[x = 0]=\sum_{i=0}^{x}\left(\begin{array}{c}x\\ i\end{array}\right)f(i+1) \]

二项式反演:

\[f(n+1)=\sum_{i=0}^n(-1)^{n-i}\left(\begin{array}{c}n\\ i\end{array}\right)[i=0] \]

\[f(n+1)=(-1)^{n}\left(\begin{array}{c}n\\ 0\end{array}\right)=(-1)^n \]

\[f(n)=(-1)^{n-1} \]

于是:

\[\max(S)=\sum_{T \in S}\limits(-1)^{|T|-1}\min(T) \]

证毕


kth 容斥:

\[Kthmax(S)=\sum_{T⊆S}(-1)^{|T|-k}\left(\begin{array}{c}{|T|-1}\\ {k-1}\end{array}\right)min(T) \]

证明:

设:

\[Kthmax(S)=\sum_{T⊆S}f(T)min(T) \]

假设某个元素从小到大后排在第 \(x\) 位(集
合大小为 \(n\)),有:

\[[x =n-k+1] *val=\sum_{i=0}^{n-x}\left(\begin{array}{c}n-x\\ i\end{array}\right)f(i+1)*val \]

\[[x = n-k+1]=\sum_{i=0}^{n-x}\left(\begin{array}{c}n-x\\ i\end{array}\right)f(i+1) \]

变换一下:

\[[n-x=k-1 ]=\sum_{i=0}^{n-x}\left(\begin{array}{c}n-x\\ i\end{array}\right)f(i+1) \]

\[[x = k-1]=\sum_{i=0}^{x}\left(\begin{array}{c}x\\ i\end{array}\right)f(i+1) \]

二项式反演:

\[f(n+1)=\sum_{i=0}^{n}(-1)^{n-i}\left(\begin{array}{c}n\\ i\end{array}\right)[i=k-1] \]

\[f(n+1)=(-1)^{n-k+1}\left(\begin{array}{c}n\\ k-1\end{array}\right) \]

\[f(n)=(-1)^{n-k}\left(\begin{array}{c}n-1\\ k-1\end{array}\right) \]

于是:

\[Kthmax(S)=\sum_{T⊆S}(-1)^{|T|-k}\left(\begin{array}{c}|T|-1\\ k-1\end{array}\right)min(T) \]

证毕


Min-Max容斥定理在期望下也成立:

\[\begin{cases} E(\max(S))=\sum_{T \in S}\limits(-1)^{|T|-1}E(\min(T))\ \ (1)\\ \\ E(\min(S))=\sum_{T \in S}\limits(-1)^{|T|-1}E(\max(T))\ \ (2)\\ \\ E(Kthmax(S))=\sum_{T⊆S}(-1)^{|T|-k}\left(\begin{array}{c}|T|-1\\ k-1\end{array}\right)E(min(T))\ \ (3)\\ \end{cases} \]

以 \((1)\) 为例:

\[E(\max(S))=\sum_{T \in S}\limits(-1)^{|T|-1}E(\min(T)) \]

证明:

由于:

\[\max(S)=\sum_{T \in S}\limits(-1)^{|T|-1}\min(T) \]

有:

\[E(\max(S))=E(\sum_{T \in S}\limits(-1)^{|T|-1}\min(T)) \]

由期望的线性性,直接整理,得:

\[E(\max(S))=\sum_{T \in S}\limits(-1)^{|T|-1}E(\min(T)) \]

证毕

[HAOI2015]按位或

#include<bits/stdc++.h>
using namespace std;
int n;
int cnt[1<<20];
double p[1<<20],ans;
int main(){
	scanf("%d",&n);
	for(int s=0;s<(1<<n);s++){
		scanf("%lf",&p[s]);
		cnt[s]=cnt[s>>1]+(s&1);
	}
	for(int i=1;i<(1<<n);i<<=1){
		for(int s1=0;s1<(1<<n);s1+=(i<<1)){
			for(int s2=0;s2<i;s2++){
				p[i+s1+s2]+=p[s1+s2];
			}
		}
	}
	for(int i=1;i<(1<<n);i++)if(1-p[i^((1<<n)-1)])ans+=((cnt[i]&1)?1:-1)/(1-p[i^((1<<n)-1)]);
	if(ans<1e-10)puts("INF");
	else printf("%.10lf",ans);

	return 0;
}

重返现世

#include<bits/stdc++.h>
using namespace std;
int n,m,t;
long long dp[15][10005];
const long long md=998244353;
inline long long pwr(long long x,long long y){
	long long res=1;
	while(y){
		if(y&1)res=res*x%md;
		x=x*x%md;y>>=1;
	}return res;
}
int main(){
	scanf("%d%d%d",&n,&t,&m);
	t=n-t+1;dp[0][0]=1;
	for(int i=1;i<=n;i++){
		int p;scanf("%d",&p);
		for(int k=m;k>=p;k--){
			for(int j=t;j;j--){
				dp[j][k]=(dp[j][k]+dp[j-1][k-p]-dp[j][k-p])%md;
			}
		}
	}
	long long ans=dp[t][0];
	for(int i=1;i<=m;i++)ans=(ans+dp[t][i]*pwr(i,md-2)%md)%md;
	printf("%lld",(ans+md)*m%md);

	return 0;
}

[PKUWC2018]随机游走

#include<bits/stdc++.h>
using namespace std;
int n,q,rt;
int ver[45],ne[45],head[45],tot,deg[45];
inline void link(int x,int y){
	ver[++tot]=y;
	ne[tot]=head[x];
	head[x]=tot;deg[y]++;
}
long long a[21],b[21];
const long long md=998244353;
inline long long pwr(long long x,long long y){
	long long res=1;
	while(y){
		if(y&1)res=res*x%md;
		x=x*x%md;y>>=1;
	}return res;
}
void dfs(int x,int fi,int S){
	if((S>>(x-1))&1)return ;
	long long tota=0,totb=0;
	for(int i=head[x];i;i=ne[i]){
		int u=ver[i];
		if(u==fi)continue;
		dfs(u,x,S);
		tota=(tota+a[u])%md;totb=(totb+b[u])%md;
	}
	a[x]=pwr(deg[x]-tota,md-2);
	b[x]=(deg[x]+totb)%md*a[x]%md;
}
long long dp[1<<18];
int cnt[1<<18];
int main(){
	scanf("%d%d%d",&n,&q,&rt);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		link(x,y);link(y,x);
	}//puts("111");
	for(int s=1;s<(1<<n);s++){
		cnt[s]=cnt[s>>1]+(s&1);
		for(int i=1;i<=n;i++)a[i]=b[i]=0;
		dfs(rt,rt,s);dp[s]=(cnt[s]&1?1:-1)*b[rt];
	}//puts("222");
	for(int i=0;i<n;i++){
    	for(int s=0;s<(1<<n);s++){
			if((s>>i)&1)continue;
			dp[s|(1<<i)]=(dp[s|(1<<i)]+dp[s])%md;
		}
	}
	while(q--){
		int k,s=0;
		scanf("%d",&k);
		while(k--){
			int x;scanf("%d",&x);
			s|=(1<<(x-1));
		}printf("%lld\n",(dp[s]+md)%md);
	}

	return 0;
}



上一篇:数据库事务系列-MySQL跨行事务模型


下一篇:递推关系与生成函数