解题:HAOI 2015 按位或

题面

 Min-Max容斥:对于集合S

$min(S)=\sum_{s∈S}(-1)^{|s|+1}max(s)$

$max(S)=\sum_{s∈S}(-1)^{|s|+1}min(s)$

那么这个题就比较板子了,$min(s)$就是$s$任意一位有值的期望,也就是某个数字和$s$有交

不太好求?再容斥一下转化成求$s$没交的,也就是补集,这是个子集和,可以FWT或者我不会的FMT

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=(1<<20)+20;
 7 const double eps=1e-10;
 8 int n,all; double ans,pro[N];
 9 int K(int s)
10 {
11     int cnt=0;
12     while(s)
13         cnt++,s-=s&-s;
14     return cnt%2?1:-1;
15 }
16 int main()
17 {
18     scanf("%d",&n),all=(1<<n)-1;
19     for(int i=0;i<=all;i++)
20         scanf("%lf",&pro[i]);
21     for(int i=2;i<=all+1;i<<=1)
22     {
23         int len=i>>1;
24         for(int j=0;j<=all;j+=i)
25             for(int k=j;k<j+len;k++)
26                 pro[k+len]+=pro[k];
27     }
28     for(int i=0;i<=all;i++)
29         if(1-pro[i^all]>eps) ans+=K(i)/(1-pro[i^all]);
30     fabs(ans)<=eps?printf("INF"):printf("%.10f",ans);
31     return 0;
32 }
View Code

 

转载于:https://www.cnblogs.com/ydnhaha/p/10307797.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值