zoukankan      html  css  js  c++  java
  • [HAOI2015] 按位或

    前置知识

    min-max 容斥

    最好做过hdu4336

    正解

    先写一下 min-max 容斥的公式吧,毕竟是我第一次学这个算法。

    [max{(S)} = sum_{T in S} (-1)^{|T|-1} min{(T)} ]

    (max{(S)}) 表示选出这个集合(的所有元素)的最晚(期望)时间,(min{(T)}) 表示选出这个集合(中的一个元素)的最早(期望)时间。 

    求出所有的 (min{(T)}) 就能算答案了。

    如果 (S)(T) 有交,那么一次就能选中 (T) 的概率可以加上 (p(S))

    现在对于每一个 (T) 要求的就是 :

    [sum_{T igcap S eq varnothing} p(S) ]

    考虑其补集,问题就是求个子集和,用高维前缀和预处理一下就完了。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 20;
    const double eps = 1e-13;
    
    int n;
    double p[1 << N];
    bool ok[N];
    
    int main() {
        scanf("%d", &n);
        for(int sta = 0; sta < (1 << n); ++sta) {
            scanf("%lf", &p[sta]);
            if(p[sta] < eps) continue; 
            for(int i = 0; i < n; ++i)
                if(sta >> i & 1)
                    ok[i] = true;
        }
        for(int i = 0; i < n; ++i)
            if(!ok[i]) {
                puts("INF");
                return 0;
            }
        for(int i = 0; i < 20; ++i)
            for(int sta = 1; sta < (1 << n); ++sta)
                if(sta >> i & 1)
                    p[sta] += p[sta ^ (1 << i)];
        double ans = 0;
        for(int sta = 1; sta < (1 << n); ++sta) {
            double g = 1 - p[((1 << n) - 1) ^ sta];
            g = 1 / g;
            if(__builtin_popcount(sta) & 1) {
                ans += g;
            } else {
                ans -= g;
            }
        }
        printf("%.7lf
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    【POJ 1958】 Strange Towers of Hanoi
    【HNOI 2003】 激光炸弹
    【POJ 3263】 Tallest Cow
    【POJ 2689】 Prime Distance
    【POJ 2777】 Count Color
    【POJ 1995】 Raising Modulo Numbers
    【POJ 1845】 Sumdiv
    6月16日省中集训题解
    【TJOI 2018】数学计算
    【POJ 1275】 Cashier Employment
  • 原文地址:https://www.cnblogs.com/Lskkkno1/p/13131189.html
Copyright © 2011-2022 走看看