luogu P3175 [HAOI2015]按位或

传送门

如果每个位置上的数字的意义是这个位置被加进集合的最早时间,那么我们要求的就是集合中最大数的期望,使用Min-Max容斥,\(E(max(S))=\sum_{T\subset S}(-1)^{|T|+1}E(min(T))\),这里的\(E(min(T))\)是集合中加进数字的期望时间,根据题意,加进一个集合数字概率为\(\sum_{s\cap T\ne\emptyset}P_s\),对应的期望,也就是\(E(min(T))=\frac{1}{\sum_{s\cap T\ne\emptyset}P_s}\)

但是\(\sum_{s\cap T\ne\emptyset}P_s\)不是很好求,可以转化成\(1-\sum_{s\cap T=\emptyset}P_s\),也就是\(1-\sum_{s\subset ?_{S}T}P_s\),高位前缀和即可

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double

using namespace std;
const int N=(1<<20)+10;
il int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n,nn;
db p[N],ans,h[N];

int main()
{
    n=rd();
    nn=(1<<n)-1;
    int ff=0;
    for(int i=0;i<=nn;++i)
    {
        scanf("%lf",&p[i]);
        if(p[i]>1e-8) ff|=i;
    }
    if(ff^nn) return puts("INF"),0;
    for(int i=1;i<=nn;i<<=1)
        for(int j=0;j<=nn;++j)
            if((j&i)==i) p[j]+=p[j^i];
    h[0]=1;
    for(int i=0;i<=nn;++i)
    {
        h[i]=-h[i^(i&(-i))];
        if(fabs(1-p[nn^i])>1e-8)ans+=h[i]*1/(1-p[nn^i]);
    }
    printf("%.8lf\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/smyjr/p/10285329.html

时间: 2024-11-10 14:32:27

luogu P3175 [HAOI2015]按位或的相关文章

bzoj4036 / P3175 [HAOI2015]按位或

bzoj4036 / P3175 [HAOI2015]按位或 是一个 min-max容斥 的板子题. min-max容斥 式子: $ \displaystyle max(S) = \sum_{T\sube S} (-1)^{|T|+1} min(T) $ 并且很优秀的是,它在期望情况下成立! 这个有什么关系呢.. 如果每一位分开考虑,如果第 $ i $ 位变成 1 的期望时间是 $ T(i) $ 那么求的是 $ E(max(T_{1\dots n})) $ 这个可以 min-max容斥 求 $

BZOJ 4036: [HAOI2015]按位或 集合幂函数 莫比乌斯变换 莫比乌斯反演

http://www.lydsy.com/JudgeOnline/problem.php?id=4036 http://blog.csdn.net/lych_cys/article/details/50898726 http://blog.csdn.net/qq_21995319/article/details/49800999 for(int i=1;i<=1;i++) for(int j=1;j<=1;j++) f[i○j]=a[i]*b[j]; 当○为按位或时,这种运算就称为集合并卷积.

[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)=

bzoj 4036 [HAOI2015]按位或——min-max容斥+FMT

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4036 题解:https://www.cnblogs.com/Zinn/p/10260126.html #include<cstdio> #include<cstring> #include<algorithm> #define db double using namespace std; const int N=25,M=(1<<20)+5; int

[HAOI2015]按位或

Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal的or)操作.选择数字i的概率是p[i].保证0<=p[i]<=1,Σp[i]=1问期望多少秒后,你手上的数字变成2^n-1. Input 第一行输入n表示n个元素,第二行输入2^n个数,第i个数表示选到i-1的概率 Output 仅输出一个数表示答案,绝对误差或相对误差不超过1e-6即可算通过.如果无解则要输出INF Sample Input 2

luogu P3178 [HAOI2015]树上操作

题目 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 输入格式 第一行包含两个整数 N, M .表示点数和操作数.接下来一行 N 个整数,表示树中节点的初始权值.接下来 N-1 行每行两个正整数 from, to , 表示该树中存在一条边 (from, to) .再接下来 M

[HAOI2015]按位或——Min-Max容斥+FWT

题面 Bzoj4036 解析 考虑$ans=E(max(t[i])), i\in S, S=\begin{Bmatrix} 1,2,\cdots, n\end{Bmatrix}$,这里$t[i]$表示第$i$位变成$1$的时间,$E(max(t[i]))$表示最后变成$1$的一位的期望时间,暂时记为$E(max(S))$,注意这个不等于$max(E(S))$ 然后套上$Min-Max$容斥,$ans=\sum_{T \subseteq S}E(min(T))$,$E(min(T))$表示$T$中

min-max容斥

这玩意儿一般都是跟概率期望结合的吧,就是下面这个式子(\(max(S)\)代表集合\(S\)中的最大值,\(min(S)\)同理): \[max(S)=\sum\limits_{T\subseteq S}(-1)^{\left | T \right |-1}min(T)\] 证明的话就考虑第\(k\)大的元素对\(max(S)\)的贡献就行了,把式子列出来之后你会发现它的贡献只有在\(k=1\)时才为\(1\),在\(k>1\)全部为\(0\) 能用它做的期望题一般都是这样的:每次操作把集合中的

「Luogu P3178」[HAOI2015]树上操作

有一棵点数为 \(N\) 的树,以点 \(1\) 为根,且树点有边权.然后有 \(M\) 个操作,分为三种: 操作 1 :把某个节点 \(x\) 的点权增加 \(a\) . 操作 2 :把某个节点 \(x\) 为根的子树中所有点的点权都增加 \(a\) . 操作 3 :询问某个节点 \(x\) 到根的路径中所有点的点权和. Luogu 分析 我们把树上问题利用 \(dfs\) 序转化成序列问题然后直接上线段树解决即可. 考虑将线段树的每个叶子结点设为在原树上的点到根的点权和.对于单点修改,当前结