由于每一个运算都有括号,因此添加的运算不会改变运算顺序

先将其建出一棵表达式树,也就是维护两个栈,是节点和运算符优先级单调递增的栈(设置左括号优先级最低,右括号弹出直至左括号)

每一次运算,也就是新建一个节点(节点上记录操作符),并将栈顶的两个节点作为其儿子即可

关于?是操作符还是变量的判定,只需要根据上一个字符是左括号还是右括号即可

建出表达式树后,令$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 }

[cf582E]Boolean Function的更多相关文章

  1. CF582E Boolean Function(DP,状态压缩,FMT)

    简单题. 我第二道自己做出来的 2900 没毛病,我没切过 2800 的题 lqy:"CF 评分 2800 是中等难度" 我活个啥劲啊 为了方便(同时压缩状态个数),先建出表达式树 ...

  2. 【CF582E】Boolean Function 树形DP+FWT

    [CF582E]Boolean Function 题意:给你一个长度为n的表达式,其中未知数有A,B,C,D和?,运算有&和|和?(表达式中用括号确定了唯一的运算顺序).?代表A,B,C,D或 ...

  3. 快速沃尔什变换&快速莫比乌斯变换小记

    u1s1 距离省选只剩 5 days 了,现在学新算法真的合适吗(( 位运算卷积 众所周知,对于最普通的卷积 \(c_i=\sum\limits_{j+k=i}a_jb_k\),\(a_jb_k\) ...

  4. WC2021 题目清单

    Day2 上午 <IOI题型与趣题分析> 来源 题目 完成情况 备注 IOI2002 Day1T1 Frog 已完成 IOI2002 Day1T2 Utopia IOI2002 Day1T ...

  5. JavaScript中function的多义性

    JavaScript 中的 function 有多重意义.它可能是一个构造器(constructor),承担起对象模板的作用: 可能是对象的方法(method),负责向对象发送消息.还可能是函数,没错 ...

  6. Function对象

    Function对象是js中很重要的一个元素,js中所有自定义的函数都是Function对象,所以String,Number,Boolean,function等都是Function对象.所以,在使用t ...

  7. 从C#到TypeScript - function

    总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...

  8. DiscuzX /source/function/function_core.php通用核心函数库文件分析

    ... <?php /** * [Discuz!] (C)2001-2099 Comsenz Inc. * This is NOT a freeware, use is subject to l ...

  9. JAVA8的java.util.function包 @FunctionalInterface

    1 函数式接口java.util.function https://www.cnblogs.com/CobwebSong/p/9593313.html 2 JAVA8的java.util.functi ...

随机推荐

  1. Apache Beam入门及Java SDK开发初体验

    1 什么是Apache Beam Apache Beam是一个开源的统一的大数据编程模型,它本身并不提供执行引擎,而是支持各种平台如GCP Dataflow.Spark.Flink等.通过Apache ...

  2. Java(42)JDK新特性之接口组成

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201666.html 博客主页:https://www.cnblogs.com/testero ...

  3. Java(30)集合五Set

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228440.html 博客主页:https://www.cnblogs.com/testero ...

  4. fpic 和 fPIC

    fpic 和 fPIC 区别 Code Gen Options (Using the GNU Compiler Collection (GCC)) 综下所述,生成适用于共享库的位置无关代码(PIC)时 ...

  5. 3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项

    3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项 The diagram below shows the essential ...

  6. 按键检测GPIO输入

    1. 项目 通过按键控制开关LED灯,按下按键灯亮,再按一下灯灭. 2. 代码 mian.c #include "stm32f10x.h" //相当于51单片机中的 #includ ...

  7. Python 做简单的登录系统

    案例 之 登录系统原创作品1 该随笔 仅插入部分代码:全部py文件源代码请从百度网盘自行下载! 链接:https://pan.baidu.com/s/1_sTcDvs5XEGDcnpoQEIrMg 提 ...

  8. 【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志

    问题描述 在App Service For Windows的环境中,我们可以通过ArmClient 工具发送POST请求在Web应用的实例中抓取网络日志,但是在App Service For Linu ...

  9. Sequence Model-week2编程题2-Emoji表情生成器

    1. Emoji表情生成器 下面,我们要使用词向量(word vector)来构建一个表情生成器. 你将实现一个模型:输入一句话 (如 "Let's go see the baseball ...

  10. 5.31日 Scrum Metting

    日期:2021年5月31日 会议主要内容概述:讨论草稿箱前后端接口,讨论账单页面设计. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 文件导入功能 ...