[FMT][DP] BZOJ 4036: [HAOI2015]按位或

来源:互联网 发布:男士商务双肩包 知乎 编辑:程序博客网 时间:2024/05/18 01:45

Description

刚开始有一个集合为空集,全集为U
每次以PT的概率给一个集合T,使拥有的那个集合变成他与这个集合的并。
问变成全集U的期望步数。

Solution

fSPS的集合幂级数。他的莫比乌斯变换

f^S=TSfT
同时有莫比乌斯反演
fS=TS(1)|T||S|f^T
题目要求的就是集合并卷积:
hS=LURUfLgR[LR=S]
通过莫比乌斯变换:
h^S====TShTLSRSfLgR(LSfL)(RSgR)f^Sg^S
所以直接FMT计算出相应的莫比乌斯变换,然后莫比乌斯反演FMT1回去就好了。
时间复杂度是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]);}