[HAOI2015] 按位或 - Min-Max容斥,快速莫比乌斯变换

初态下,分数为 \(0\)。每秒钟,随机选择一个 \([0,2^n-1]\) 的数字与当前的数字做按位或运算。选择数字 \(i\) 的概率是 \(p_i\),求分数达到 \(2^n-1\) 的期望时间。\(n\leq 20\)

Solution

先介绍一下 Min-Max 容斥原理。设 \(\max(S),\min(S)\) 分别是集合 \(S\) 中的最大值与最小值,则有
\[
\max(S)=\sum_{T\subseteq S} (-1)^{|T|+1} \min(T)
\\min(S)=\sum_{T\subseteq S} (-1)^{|T|+1} \max(T)
\]
Min-Max 容斥原理对随机变量的期望成立。

回到原问题,对于某个位置集合,考虑将每个位变为 \(1\) 的时间扔进一个集合,那么 \(\min(S)\) 是集合中第一个变 \(1\) 元素的时间,\(\max(S)\) 是最后一个。

于是答案就是 \(E(\max(U))\),其中 \(U\) 为全集。利用 Min-Max 容斥原理我们可以将它转化为求对于每一个子集的 \(E(\min(S))\),而 \(\min(S)\) 符合几何分布,于是有
\[
\begin{aligned}
E(\min(S)) &= \sum_{i=1}^{\infty} iP(\min(S)=i)
\&= \sum_{i=1}^\infty i(\sum_{TS=\varnothing}p_T)^{i-1}(1-\sum_{TS=\varnothing}p_T)
\&= \frac{1}{1-\sum_{TS=\varnothing}p_T}
\end{aligned}
\]
于是现在我们需要对所有 \(S\subseteq U\),求出 \(\sum_{TS=\varnothing} p_T\)

考虑 FMT,可以用来求出 \(\forall S,\ g(S)=\sum_{T\subseteq S} f(T)\)

#include <bits/stdc++.h>
using namespace std;

double a[2000005],ans;
int n;

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=0;i<1<<n;i++) cin>>a[i];
    int up=1<<n;
    for(int k=1;k<up;k<<=1)
        for(int s=0;s<up;s+=k<<1)
            for(int i=s;i<s+k;i++)
            {double a0=a[i];double a1=a[i+k];a[i]=a0;a[i+k]=a0+a1;}
    for(int i=1;i<up;i++) {
        if(1-a[(up-1)^i]<1e-10) {
            puts("INF");
            return 0;
        }
        ans += (__builtin_popcount(i)%2?1:-1)*1/(1-a[(up-1)^i]);
    }
    printf("%.8lf",ans);
}

原文地址:https://www.cnblogs.com/mollnn/p/12397445.html

时间: 2024-10-31 03:31:56

[HAOI2015] 按位或 - Min-Max容斥,快速莫比乌斯变换的相关文章

BZOJ 2440 完全平方数 (容斥+莫比乌斯反演+二分)

2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1673  Solved: 799 [Submit][Status][Discuss] Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些 数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而 这丝毫不影响他对其他数的热爱. 这天是小X的生日,小 W 想送一个数给他作为生日礼物.当然他不能送一 个

HDU 1695 GCD(容斥 or 莫比乌斯反演)

这题可以用容斥做,然而效率并不高.. 于是学了下莫比乌斯反演(资料百度找) 求出mo数组后 设f(x)为gcd为x的种数 F(x)为gcd为x倍数的种数 那么显然F(x) = (b / x) * (d / x) 莫比乌斯反演之后,得到f(x) = sum(mo[i] * F(i)). 然后还要容斥减去对称重复的.对称重复的情况为min(b, d)小的中,求一遍除2,(因为存在x = y的情况只有(1,1)一种) 最后还要注意特判下k == 0的情况 代码: #include <cstdio>

hdu 6390 欧拉函数+容斥(莫比乌斯函数) GuGuFishtion

http://acm.hdu.edu.cn/showproblem.php?pid=6390 题意:求一个式子 题解:看题解,写代码 第一行就看不出来,后面的sigma公式也不会化简.mobius也不会 就自己写了个容斥搞一下(才能维持现在的生活) //别人的题解https://blog.csdn.net/luyehao1/article/details/81672837 #include <iostream> #include <cstdio> #include <cstr

BZOJ 2301 [HAOI2011]Problem b (容斥+莫比乌斯反演+分块优化 详解)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2096  Solved: 909 [Submit][Status][Discuss] Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Out

POJ 3904 Sky Code (容斥+莫比乌斯反演)

Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1831   Accepted: 570 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to ste

UESTC 618 无平方因子数 (容斥 + 莫比乌斯反演)

无平方因子数 Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit  Status 无平方因子数即对于任意一个素数p,p2都不会整除那个数,如1 , 5=5 , 15=3×5都是无平方因子数,而20=22×5不是.现在给定一个n (1≤n<1012) ,求区间[1,n]中无平方因子数的个数. Input 第一行有个整数T,代表数据组数(T≤10) 接下来有T行,每行有个整数n

HDU 5212 Code(容斥 或 莫比乌斯反演)

Code Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description WLD likes playing with codes.One day he is writing a function.Howerver,his computer breaks down because the function is too powerful.He is ve

「总结」容斥。二.反演原理

二.反演原理 0.综述 说一下个人对反演的理解. 反演是一种手段,一种处理已知信息和未知信息关系的手段,用来得到未知信息的方式.也就是以一种既定的手段在较小的时间复杂度内用已知的信息得到未知的信息. 还有$zsq$学长更加浅显的解读. 反演一般就是把一个好看但难算的式子转化成一个难看且难算的式子在转化为一个难看但好算的式子. 先来一个裸一点的反演 下面要说我知道的四种反演. 子集反演,针对的是集合交并的容斥. 二项式反演,针对组合原理的容斥. 莫比乌斯反演,针对约数和倍数的容斥. 斯特林反演,针

D. Unusual Sequences(容斥)

D. Unusual Sequences 隔板法 + 容斥原理 1 //容斥(莫比乌斯反演) 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define LL long long 5 const int mod = 1e9+7; 6 LL quickpow(LL a, LL b, LL mod){ 7 LL temp = a % mod, res = 1; 8 while(b){ 9 if(b & 1) res = res *