• [洛谷P3175][HAOI2015]按位或


    题目大意:刚开始有一个数$x=0$,每秒钟有一个数$yin[0,2^n)(nleqslant20)$按一定概率随机出现,数$i$的概率为$p_i$,保证$sumlimits_{i=0}^{2^n-1}p_i=1$。然后$x o x|y$,问期望多少时间后,$x=2^n-1$

    题解:$Min-Max$容斥
    $$
    max(S)=sumlimits_{Tsubseteq S}(-1)^{|T|+1}min(T)\
    min(S)=sumlimits_{Tsubseteq S}(-1)^{|T|+1}max(T)
    $$
    而且,它在期望下成立,即:
    $$
    E(max(S))=sumlimits_{Tsubseteq S}(-1)^{|T|+1}E(min(T))\
    E(min(S))=sumlimits_{Tsubseteq S}(-1)^{|T|+1}E(max(T))
    $$
    这道题相当于求$E(max(S))$,也就是说,现在需要求$E(min(S))$。令$s(S)$表示随机出来的数$yin S$的概率,即$sumlimits_{yin S}p_y$,这可以用$FWT$解决。

    求$E(min(S))$,就枚举选了多少次数与$S$都没有交
    $$
    egin{align*}
    E(min(S))&=sumlimits_{i=0}^{infty}s(ar S)^i(i+1)(1-s(ar S))\
    &=(1-s(ar S))dfrac1{(1-s(ar S))^2}\
    &=dfrac1{1-s(ar S)}
    end{align*}
    $$
    然后$Min-Max$容斥一下就好了

    卡点:

    C++ Code:

    #include <algorithm>
    #include <cstdio>
    #define N 1048576 | 3
    
    int lim, U;
    void FWT(double *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) A[i + j + mid] += A[i + j];
    }
    
    int n;
    double p[N], s[N], f[N];
    int main() {
    	scanf("%d", &n); lim = 1 << n, U = lim - 1;
    	for (int i = 0; i < lim; ++i) scanf("%lf", p + i);
    	std::copy(p, p + lim, s);
    	FWT(s);
    	for (int i = 0; i < lim - 1; ++i) if (s[i] == 1) {
    		puts("INF");
    		return 0;
    	}
    	for (int i = 1; i < lim; ++i) f[i] = 1 / (1. - s[U ^ i]);
    
    	double ans = 0;
    	for (int i = 1; i < lim; ++i) {
    		if (__builtin_popcount(i) & 1) ans += f[i];
    		else ans -= f[i];
    	}
    	printf("%.6lf
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    浅水方程
    Delaunay三角剖分算法
    计算机图形学知名期刊杂志(转载)
    Sql 主键自增
    Skinny triangle
    开源免费天气预报接口API以及全国所有地区代码!!
    Navier Stokes(纳维叶-斯托克斯)方程
    java.util.Date_与_java.sql.Date互转_及_字符串转换为日期时间格式
    2015最后一天
    html标签
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10370630.html
Copyright © 2020-2023  润新知