ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【luogu P3175】按位或(min-max容斥)(高维前缀和 / FWT)

2022-07-15 08:00:51  阅读:155  来源: 互联网

标签:limits min luogu sum 容斥 max FWT subseteq


按位或

题目链接:luogu P3175

题目大意

有一个数 0 你一开始,然后每次你可以与上一个数 0~2^n-1 中的,每个数有它被你选择的概率。
然后问你期望要弄多少次才能使得这个数变成 2^n-1。

思路

首先这个弄成 \(2^n-1\) 显然不好弄,我们考虑一个神奇的东西,就是 min-max 容斥。
因为这个 \(\min,\max\) 它不一定要是最大值最小值,它可以是最早出现最晚出现之类的。
所以我们可以视作最后一次操作让 \(2^n-1\) 完成是最晚出现,那最早出现就是第一次开始拼 \(2^n-1\)。
那再看回去 min-max 容斥的式子:\(\max(T)=\sum\limits_{T\subset S}(-1)^{|S|}\min(S)\)

那我们就要求出每个子集第一次被覆盖到的期望时间,设为 \(f(S)\)。
考虑生成函数,对于每次如果覆盖到就结束,没有覆盖到就要继续,然后没有覆盖到相当于覆盖了 \(S\) 的补集(这里设为 \(nS\))的子集,然后设一次操作选的集合是 \(S\) 的子集的概率为 \(P(S)\)。
\(f(S)=P(nS)f(S)+1\)
\(f(S)=\dfrac{1}{1-P(nS)}\)

然后再看怎么求 \(P(S)\),这个其实简单,直接一个高位前缀和就好了。
不过后来发现也可以用 FWT 之类的。

就是好像是对于 FWT 的或,它是这样的:
\(C_i=\sum\limits_{j|k=i}A_jB_k\)
然后如果设 \(f(C_i)=\sum\limits_{j\subseteq i}C_j\)
那 \(f(C_i)=\sum\limits_{j|k\subseteq i}A_jB_k=\sum\limits_{j\subseteq i,k\subseteq i}A_jB_k=f(A_i)f(B_i)\)

那 FWT 不就是跟 FFT 差不多弄个变换然后逆变换吗?
那我们 FWT 或变换得到的就是子集和!

很神奇吧。

然后又一些细节,就是记得有个东西是如果无解输出 INF。
那首先如果答案是 \(0\) 你得 INF,而且可能因为你 \(f(S)\) 的求里面可能下面是 \(0\)(就 \(P(nS)=1\)),所以碰到这些你要直接跳过,不然会出问题。

代码

#include<cstdio>

using namespace std;

const int N = 20;
const double eps = 1e-8;
int n, xs[1 << N];
double p[1 << N], f[1 << N], ans;

int main() {
	scanf("%d", &n);
	for (int i = 0; i < (1 << n); i++) scanf("%lf", &p[i]);
	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < (1 << n); j++)
			if ((j >> i) & 1) p[j] += p[j ^ (1 << i)];
	}
	
	xs[0] = -1;
	for (int i = 1; i < (1 << n); i++) {
		xs[i] = -xs[i ^ (i & (-i))];
		if (1 - p[i ^ ((1 << n) - 1)] < eps) continue;
		f[i] = 1.0 / (1 - p[i ^ ((1 << n) - 1)]);
		ans += f[i] * xs[i];
	}
	if (ans < eps) printf("INF");
		else printf("%.8lf", ans);
	
	return 0;
}

标签:limits,min,luogu,sum,容斥,max,FWT,subseteq
来源: https://www.cnblogs.com/Sakura-TJH/p/luogu_P3175.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有