显然可以拆位,20个位单独考虑
dp[i][j]=前i对OiAi,满足第j位为1的概率
dp[i][j]=dp[i−1][j]+(1−dp[i−1][j])∗(1−pi) Oi= or 且(ai>>j) and 1=1
dp[i][j]=dp[i−1][j]∗pi Oi=and且(ai>>j) and 1=0
dp[i][j]=dp[i−1][j]∗pi+(1−dp[i−1][j])∗(1−pi) Oi=xor且(ai>>j)and 1=1
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int N = 1000+5;
double p[N];
int a[N];
char o[N];
double d[2][22];
double dp(int n){
MEM(d,0);
double *d1=d[0],*d2=d[1];
for(int i=0;i<=20;++i){
if((a[0]>>i)&1){
d1[i]=1;
}
}
for(int i=1;i<=n;++i){
for(int j=0;j<=20;++j){
d2[j]=d1[j];
if(((a[i]>>j)&1)&&o[i]=='|'){
d2[j]=d1[j]+(1-d1[j])*(1-p[i]);
}
if(!((a[i]>>j)&1)&&o[i]=='&'){
d2[j]=d1[j]*p[i];
}
if(((a[i]>>j)&1)&&o[i]=='^'){
d2[j]=d1[j]*p[i]+(1-d1[j])*(1-p[i]);
}
}
swap(d1,d2);
}
double ans=0;
int t=1;
for(int i=0;i<=20;++i){
ans+=d1[i]*t;
t*=2;
}
return ans;
}
int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w1.txt","w",stdout);
int n;
while(~scanf("%d",&n)){
for(int i=0;i<=n;++i){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;++i){
scanf("%*c%c",&o[i]);
}
for(int i=1;i<=n;++i){
scanf("%lf",&p[i]);
}
printf("%f\n",dp(n));
}
return 0;
}