【BZOJ4036】【LOJ2127】【HAOI2015】按位或
Min-Max容斥+子集和变换即可。
下面不区分普通的数和集合。
设第一次访问第位的时间为,设为,则原题就是求。
直接套用Min-Max容斥可得:
考虑计算,设
由等比数列求和公式容易发现
于是子集和变换求出所有的即可,注意特判INF的情况。
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int MAXSIZE=30000020;int bufpos;char buf[MAXSIZE];#define NEG 0void init(){#ifdef LOCALfreopen("4036.txt","r",stdin);#endifbuf[fread(buf,1,MAXSIZE,stdin)]=' ';bufpos=0;}#if NEGint readint(){bool isneg;int val=0;for(;!isdigit(buf[bufpos]) && buf[bufpos]!='-';bufpos++);bufpos+=(isneg=buf[bufpos]=='-');for(;isdigit(buf[bufpos]);bufpos++)val=val*10+buf[bufpos]-'0';return isneg?-val:val;}#elseint readint(){int val=0;for(;!isdigit(buf[bufpos]);bufpos++);for(;isdigit(buf[bufpos]);bufpos++)val=val*10+buf[bufpos]-'0';return val;}#endifchar readchar(){for(;isspace(buf[bufpos]);bufpos++);return buf[bufpos++];}int readstr(char* s){int cur=0;for(;isspace(buf[bufpos]);bufpos++);for(;!isspace(buf[bufpos]);bufpos++)s[cur++]=buf[bufpos];s[cur]='\0';return cur;}double p[1<<20];char s[101];int main(){init();int n=readint();for(int i=0;i<(1<<n);i++){readstr(s);p[i]=strtod(s,0);}for(int i=0;i<n;i++)for(int j=0;j<(1<<n);j++)if (j>>i&1)p[j]+=p[j^(1<<i)];double ans=0;for(int i=1;i<(1<<n);i++){double t=1-p[(1<<n)-1-i];if (t<1e-9)return puts("INF"),0;t=1/t;if (__builtin_parity(i))ans+=t;else ans-=t;}printf("%.10f",ans);}
Written with StackEdit.
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
本文链接:https://www.q234rty.top/2018/02/25/bzoj4036/
