Description
刚开始有一个集合为空集,全集为
U
。
每次以
问变成全集
Solution
设 fS 为 PS 的集合幂级数。他的莫比乌斯变换
f^S=∑T⊆SfT
同时有莫比乌斯反演
fS=∑T⊆S(−1)|T|−|S|f^T
题目要求的就是集合并卷积:
hS=∑L⊆U∑R⊆UfLgR[L∪R=S]
通过莫比乌斯变换:
h^S====∑T⊆ShT∑L⊆S∑R⊆SfLgR(∑L⊆SfL)(∑R⊆SgR)f^Sg^S
所以直接
FMT
计算出相应的莫比乌斯变换,然后莫比乌斯反演
FMT−1
回去就好了。
时间复杂度是 O(2nn) 的。
using namespace std;
const int N = 22;
const int eps = 1e-8;
int n, m;
double p[1 << N];
inline void FMT(double *a, int n, int f) {
int m = 1 << n;
for (int i = 0; i < n; i++)
for (int S = 1; S < m; S++)
if ((S >> i) & 1)
a[S] += f * a[S ^ (1 << i)];
}
int main(void) {
freopen("1.in", "r", stdin);
scanf("%d", &n); m = 1 << n;
for (int i = 0; i < m; i++)
scanf("%lf", &p[i]);
FMT(p, n, 1);
for (int i = 0; i < m; i++)
if (fabs(1 - p[i]) <= eps) p[i] = 0;
else p[i] = 1 / (p[i] - 1);
FMT(p, n, -1);
if (fabs(p[m - 1]) <= eps) printf("INF\n");
else printf("%.10lf\n", p[m - 1]);
}