[cf582E]Boolean Function
由于每一个运算都有括号,因此添加的运算不会改变运算顺序
先将其建出一棵表达式树,也就是维护两个栈,是节点和运算符优先级单调递增的栈(设置左括号优先级最低,右括号弹出直至左括号)
每一次运算,也就是新建一个节点(节点上记录操作符),并将栈顶的两个节点作为其儿子即可
关于?是操作符还是变量的判定,只需要根据上一个字符是左括号还是右括号即可
建出表达式树后,令$S$是一个$2^{2^{4}}$的二进制数,表示定义$f_{k,S}$表示以$k$为根的子树中,每一种取值的答案为$S$在该位置上的值的方案数,合并根据or或and做卷积,复杂度为$o(Ln2^{n})$($L=|s|$)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 505 4 #define S (1<<16) 5 #define mod 1000000007 6 stack<int>st_op,st_num; 7 int V,n,ans,a[N],ls[N],rs[N],vis[105],f1[S],f2[S],f3[S],g[11][S],f[N][S]; 8 char s[N]; 9 int turn_num(int k){ 10 if (('A'<=s[k])&&(s[k]<='D'))return s[k]-'A'; 11 if (('a'<=s[k])&&(s[k]<='d'))return s[k]-'a'+4; 12 if ((s[k]=='?')&&((!k)||(s[k-1]=='(')))return 8; 13 return -1; 14 } 15 void merge(){ 16 a[++V]=st_op.top(); 17 st_op.pop(); 18 rs[V]=st_num.top(); 19 st_num.pop(); 20 ls[V]=st_num.top(); 21 st_num.pop(); 22 st_num.push(V); 23 } 24 void FWT_or(int *a,int p){ 25 for(int i=0;i<(1<<4);i++) 26 for(int j=0;j<S;j++) 27 if (j&(1<<i))a[j]=((a[j]+p*a[j^(1<<i)])%mod+mod)%mod; 28 } 29 void FWT_and(int *a,int p){ 30 for(int i=0;i<(1<<4);i++) 31 for(int j=0;j<S;j++) 32 if (j&(1<<i))a[j^(1<<i)]=((a[j^(1<<i)]+p*a[j])%mod+mod)%mod; 33 } 34 void dfs(int k){ 35 if ((!ls[k])&&(!rs[k]))return; 36 dfs(ls[k]); 37 dfs(rs[k]); 38 if (!a[k]){ 39 FWT_and(f[ls[k]],1); 40 FWT_and(f[rs[k]],1); 41 for(int i=0;i<S;i++)f[k][i]=1LL*f[ls[k]][i]*f[rs[k]][i]%mod; 42 FWT_and(f[k],-1); 43 } 44 if (a[k]==1){ 45 FWT_or(f[ls[k]],1); 46 FWT_or(f[rs[k]],1); 47 for(int i=0;i<S;i++)f[k][i]=1LL*f[ls[k]][i]*f[rs[k]][i]%mod; 48 FWT_or(f[k],-1); 49 } 50 if (a[k]==2){ 51 memcpy(f1,f[ls[k]],sizeof(f1)); 52 memcpy(f2,f[rs[k]],sizeof(f2)); 53 FWT_and(f1,1); 54 FWT_and(f2,1); 55 for(int i=0;i<S;i++)f3[i]=1LL*f1[i]*f2[i]%mod; 56 FWT_and(f3,-1); 57 FWT_or(f[ls[k]],1); 58 FWT_or(f[rs[k]],1); 59 for(int i=0;i<S;i++)f[k][i]=1LL*f[ls[k]][i]*f[rs[k]][i]%mod; 60 FWT_or(f[k],-1); 61 for(int i=0;i<S;i++)f[k][i]=(f[k][i]+f3[i])%mod; 62 } 63 } 64 int main(){ 65 scanf("%s",s); 66 n=strlen(s); 67 for(int i=0;i<n;i++){ 68 int p=turn_num(i); 69 if (p!=-1){ 70 a[++V]=p; 71 st_num.push(V); 72 if ((!st_op.empty())&&(st_op.top()!=-1))merge(); 73 } 74 else{ 75 if (s[i]=='(')st_op.push(-1); 76 if (s[i]=='&')st_op.push(0); 77 if (s[i]=='|')st_op.push(1); 78 if (s[i]=='?')st_op.push(2); 79 if (s[i]==')'){ 80 st_op.pop(); 81 if ((!st_op.empty())&&(st_op.top()!=-1))merge(); 82 } 83 } 84 } 85 while (!st_op.empty())merge(); 86 for(int i=0;i<8;i++){ 87 int sta=0; 88 for(int j=0;j<(1<<4);j++) 89 if (((j&(1<<i%4))>0)^(i>=4))sta+=(1<<j); 90 g[i][sta]=1; 91 g[8][sta]++; 92 } 93 for(int i=1;i<=V;i++) 94 if ((!ls[i])&&(!rs[i]))memcpy(f[i],g[a[i]],sizeof(f[i])); 95 dfs(V); 96 memset(vis,-1,sizeof(vis)); 97 scanf("%d",&n); 98 for(int i=1;i<=n;i++){ 99 int k=0,p; 100 for(int j=0;j<4;j++){ 101 scanf("%d",&p); 102 if (p)k+=(1<<j); 103 } 104 scanf("%d",&vis[k]); 105 } 106 for(int i=0;i<S;i++){ 107 bool flag=0; 108 for(int j=0;j<(1<<4);j++) 109 if ((vis[j]>=0)&&(((i&(1<<j))>0)!=vis[j])){ 110 flag=1; 111 break; 112 } 113 if (!flag)ans=(ans+f[V][i])%mod; 114 } 115 printf("%d",ans); 116 }