首页 > 其他分享 >[HAOI2015] 按位或

[HAOI2015] 按位或

时间:2023-02-24 15:47:05浏览次数:56  
标签:limits min max sum HAOI2015 按位 subseteq displaystyle

[HAOI2015]按位或

Luogu P3175

题目描述

刚开始你有一个数字 \(0\),每一秒钟你会随机选择一个 \([0,2^n-1]\) 的数字,与你手上的数字进行或(C++,C 的 |,pascal 的 or)操作。选择数字 \(i\) 的概率是 \(p_i\)。保证 \(0\leq p_i \leq 1\),\(\sum p_i=1\) 。问期望多少秒后,你手上的数字变成 \(2^n-1\)。

输入格式

第一行输入 \(n\) 表示 \(n\) 个元素,第二行输入 \(2^n\) 个数,第 \(i\) 个数表示选到 \(i-1\) 的概率。

输出格式

仅输出一个数表示答案,绝对误差或相对误差不超过 \(10^{-6}\) 即可算通过。如果无解则要输出 INF

样例 #1

样例输入 #1

2
0.25 0.25 0.25 0.25

样例输出 #1

2.6666666667

提示

对于 \(100\%\) 的数据,\(n\leq 20\)。

Solution

设 \(\min\{S\}\) 表示 \(S\) 中第一个变为 \(1\) 的时间,\(\max\{S\}\) 表示 S 中最后一个变为 \(1\) 的时间(\(S\) 是一个二进制数)。那么有等式:

\[\begin{array}{}\displaystyle\max\{S\}=\sum\limits_{T\subseteq S} (-1)^{|T|+1}\min\{T\}\\\displaystyle\min\{S\}=\sum\limits_{T\subseteq S} (-1)^{|T|+1}\max\{T\}\end{array} \]

这个等式也叫做 \(\min/\max\) 容斥,并且这个等式在期望意义下也成立:

\[\begin{array}{}\displaystyle E(\max\{S\})=\sum\limits_{T\subseteq S}(-1)^{|T|+1}E(\min\{T\})\\\displaystyle E(\min\{S\})=\sum\limits_{T\subseteq S}(-1)^{|T|+1}E(\max\{T\})\end{array} \]

此题要求的显然是 \(E(\max\{S\}),S=(2^n-1)\),并且数据范围允许枚举集合 \(T\),那么考虑如何计算 \(E(\min\{T\})\)。有式子:

\[E(\min\{T\})=\dfrac 1 {\displaystyle\sum\limits_{G\cap T\neq \varnothing} P(G)} \]

其中 \(P(G)\) 表示出现的数是 \(G\) 的概率。由于 \(G\cap T\neq \varnothing\) 并不好计算,正难则反,令 \(X=\complement_{S} T\),即 \(X=T\oplus S\),那么有 \(\forall G\cap T=\varnothing,G\subseteq X\),那么不符合条件的 \(G\) 就好计算了,处理一下 \(X\) 的子集和即可,记 \(X\) 的子集和为 \(P'(X)\),那么就有:

\[E(\min\{T\})=\dfrac 1 {1-P'(x)} \]

对于 \(X\) 的子集和,显然有 \(P'(X)=\displaystyle\sum\limits_{X=Y\lor X}P(Y)\),这个就是 FWT 的形式,直接用 FWT 处理即可。

时间复杂度 \(\mathcal O(n2^n)\)。

#include<bits/stdc++.h>
using namespace std;
constexpr int _N = (1 << 20) + 5;
constexpr double eps = 1e-8;
int n, N; double P[_N], ans;
void FWTor(double *A) {
	for (int i = 1; i < N; i <<= 1)
		for (int j = 0; j < N; j += i << 1)
			for (int k = 0; k < i; ++k)
				A[i + j + k] += A[j + k];
}
signed main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n; N = 1 << n;
	for (int i = 0; i < N; ++i) cin >> P[i];
	FWTor(P);
	for (int i = 1; i < N; ++i) if ((1 - P[(N - 1) ^ i]) > eps)
		ans += ((__builtin_popcount(i) & 1) ? 1 : -1) / (1 - P[(N - 1) ^ i]);
	if (ans < eps) cout << "INF" << '\n';
	else cout << fixed << setprecision(10) << ans << '\n';
}

标签:limits,min,max,sum,HAOI2015,按位,subseteq,displaystyle
From: https://www.cnblogs.com/hanx16msgr/p/17151711.html

相关文章

  • kx00010-顺序表--按位置删除表元素remove
    一、顺序表结构定义#defineINIT_SIZE10 //顺序表初始容量typedefvoid(myOpFunType)(void*); //定义操作函数类型typedefintseqType; //定义顺序表元素类型......
  • &(按位与运算)、|(按位或运算)、^(异或运算)
    按位与运算符(&)对俩个数据进行二进制按位与运算。二进制规则:0&0=0;  0&1=0;   1&0=0;  1&1=1双1为1,否则为0.例:102&255即:01100110&11111111=011001......
  • ~按位取反
    定义#include<stdio.h>intmain(){inta=0;printf("%d\n",~a);return0;}a=0;00000000000000000000000000000000~a:11111111111111111111111111111111-补码反码:11111111......
  • 按位计算TMMBN中的MxTBR
    上周处理RTCP消息中发现项目小伙伴处理TMMBR消息中遇到了问题。主要是小伙伴不晓得对于MxTBR中的Exp、Mantissa以及OverHead怎么赋值。因为这三个对象的赋值都没有按照完......
  • 【LeetCode周赛-312】子数组按位与最大值、并查集(图)
    周赛链接:​​​https://leetcode.cn/contest/weekly-contest-312/​​A.2418.按身高排序题目描述:给你一个字符串数组names,和一个由互不相同的正整数组成的数组heig......
  • 为什么1按位取反的结果是-2?
    假设计算机存取一个数用8位表示按位取反要考虑符号位(最高位为0则正,反之则为负)5=00000101取反11111010但是符号位发生改变,计算机中数的存储都是用补码进行存储的,正数......
  • 「HAOI2015」数字串拆分
    「HAOI2015」数字串拆分定义\(f_s\)将\(s\)拆分成\(1\simm\)的数的和的方案数,\(g_s\)将\(s\)这个数字串分割成若干个数字(允许前导\(0\)),设它们的和为\(x\),那......
  • java中用整数相除获得小数并按位数输出
      俩个int类型的数据进行运算,结果也是int类型的,0.33333转为int类型为0.0;要求保留两位小数输出:System.out.printf("%.2f",b);//保留两位小数输出......
  • 顺序表-00011-按位置删除元素,remove
    顺序表结构定义typedefintseqType; //定义顺序表数据类型//定义顺序表的结构体typedefstructt_sList{ seqType*pbase; //表基址 intcapacity; //表......
  • 顺序表-00008-按位置插入,insert
    顺序表结构定义typedefintseqType; //定义顺序表数据类型//定义顺序表的结构体typedefstructt_sList{ seqType*pbase; //表基址 intcapacity; //表......