这个题关键在于求一个集合所有子集之和,然后来一遍 $or$ 的正变换即可.
code:
#include <bits/stdc++.h> #define N 21 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int bin[N],size[1<<N],n; double p[1<<N],F[1<<N],g[1<<N],A[1<<N],B[1<<N]; void exi() { printf("INF\n"),exit(0); } int lowbit(int x) { return x&(-x); } void FWT(double *a,int len) { for(int i=1;i<len;i<<=1) for(int j=0;j<len;j+=i<<1) for(int k=0;k<i;++k) a[j+k+i]+=a[j+k]; } int main() { // setIO("input"); bin[0]=1; for(int i=1;i<N;++i) bin[i]=bin[i-1]<<1; scanf("%d",&n); int is=0,to=bin[n]-1; for(int i=0;i<bin[n];++i) { scanf("%lf",&p[i]),F[i]=p[i]; if(p[i]) is|=i; } if(is!=bin[n]-1) exi(); for(int i=1;i<bin[n];++i) size[i]=size[i-lowbit(i)]+1; FWT(F,bin[n]); double ans=0; for(int i=1;i<bin[n];++i) { double opt=(size[i]%2)?1:-1; ans+=opt/(1.0-F[to^i]); } printf("%.8f\n",ans); return 0; }
LOJ #2127. 「HAOI2015」按位或 (min-max 容斥 + FWT)
原文:https://www.cnblogs.com/guangheli/p/12821294.html