[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 }
[cf582E]Boolean Function的更多相关文章
- CF582E Boolean Function(DP,状态压缩,FMT)
简单题. 我第二道自己做出来的 2900 没毛病,我没切过 2800 的题 lqy:"CF 评分 2800 是中等难度" 我活个啥劲啊 为了方便(同时压缩状态个数),先建出表达式树 ...
- 【CF582E】Boolean Function 树形DP+FWT
[CF582E]Boolean Function 题意:给你一个长度为n的表达式,其中未知数有A,B,C,D和?,运算有&和|和?(表达式中用括号确定了唯一的运算顺序).?代表A,B,C,D或 ...
- 快速沃尔什变换&快速莫比乌斯变换小记
u1s1 距离省选只剩 5 days 了,现在学新算法真的合适吗(( 位运算卷积 众所周知,对于最普通的卷积 \(c_i=\sum\limits_{j+k=i}a_jb_k\),\(a_jb_k\) ...
- WC2021 题目清单
Day2 上午 <IOI题型与趣题分析> 来源 题目 完成情况 备注 IOI2002 Day1T1 Frog 已完成 IOI2002 Day1T2 Utopia IOI2002 Day1T ...
- JavaScript中function的多义性
JavaScript 中的 function 有多重意义.它可能是一个构造器(constructor),承担起对象模板的作用: 可能是对象的方法(method),负责向对象发送消息.还可能是函数,没错 ...
- Function对象
Function对象是js中很重要的一个元素,js中所有自定义的函数都是Function对象,所以String,Number,Boolean,function等都是Function对象.所以,在使用t ...
- 从C#到TypeScript - function
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- DiscuzX /source/function/function_core.php通用核心函数库文件分析
... <?php /** * [Discuz!] (C)2001-2099 Comsenz Inc. * This is NOT a freeware, use is subject to l ...
- JAVA8的java.util.function包 @FunctionalInterface
1 函数式接口java.util.function https://www.cnblogs.com/CobwebSong/p/9593313.html 2 JAVA8的java.util.functi ...
随机推荐
- nGrinder 参数使用
背景: 性能测试中为了更加接近真实模拟现实应用,对于提交的信息每次都需要提交不同的数据,或使用不同的值,最为典型的就是登录时的账号. 性能测试工具需要提供动态参数化功能,如商业化的LoadRunner ...
- 题解 2020.10.24 考试 T3 数列
题目传送门 题目大意 给出一个数 \(n\),你要构造一个数列,满足里面每个数都是 \(n\) 的因子,且每一个数与前面不互质的个数不超过 \(1\).问有多少种合法方案. 保证 \(n\) 的不同质 ...
- 内网渗透DC-5靶场通关
个人博客地址:点我 DC系列共9个靶场,本次来试玩一下一个 DC-5,只有一个flag,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶 ...
- JavaScript之原型与原型链
前言 ❝ JavaScript常被描述为一种「基于原型的语言」--每个对象都拥有一个「原型对象」,对象以其原型为模板.从原型继承属性和放法.原型对象也可能拥有原型,并从中继承属性和方法,一层一层以此类 ...
- 【UE4 设计模式】装饰器模式 Decorator Pattern
概述 描述 动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活.是一种对象结构型模式. 套路 抽象构件(Component) 具体构 ...
- 记一个非常诡异的关于 shared_ptr 的 bug
问题描述 今天写项目的时候遇见一个特别诡异的 bug,体现在在执行某条语句时,程序会莫名崩溃,并且给出的错误信息也非常难懂,只有一个malloc(): invalid size (unsorted)错 ...
- Scrum Meeting 0425
零.说明 日期:2021-4-25 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 完成登录.注册A ...
- C/C++编程笔记:浪漫流星雨表白装b程序
作为一个未来可能会成为一个专业程序员的小伙们,不知道你们现在学到哪里了,学了点东西之后有没有想在你女朋友面前装个大大的b呢,今天小编就给你一个机会来研究一下下边的代码吧,保证大写的N,当然大佬是排除在 ...
- Linux入门必须养成的七大习惯
对于很多Linux初学者来说,在刚开始使用linux系统时会感到很多的不适.这里为大家整理了自己以前linux入门时别人告诉我的七个习惯.我相信如果你运用了这七个习惯,在你使用Linux时你会感觉更安 ...
- Linux入门所必备的Linux命令和C语言基础
文件和目录(底部有视频资料) cd /home 进入 '/ home' 目录' cd - 返回上一级目录 cd -/- 返回上两级目录 cd 进入个人的主目录 cd ~user1 进入个人的主目录 c ...