提供 \(k\) 个变量 \((k\leq 4)\) 可独立取值为 \(0,1\),两种运算分别等价于 \(\neg a\) 和 \(\neg a \lor b\) 。

你需要恰好使用 \(n\) 个运算符构造一个公式 \(Q\) ,一共 \(m\) 组询问 \((m\leq 500)\),每次寻味有给定一个恰好含有一个 \(Q\) 的公式 \(P\ (|P|\leq 4000)\) ,求有多少种合法的 \(Q\) 使得无论 \(k\) 个变量取何值,\(P\) 的值总为真。

考虑对于 \(k\) 个变量一共有 \(2^k\) 种可能的取值。假设 \(Q\) 已经构造完毕, \(Q\) 在 \(2^k\) 种变量取值可能中分别对应 \(2^k\) 个\(0,1\),将这 \(2^k\) 个 \(0,1\) 压成一个 \(2^k\) 位的状态,那么一个 \(Q\) 对应着 \(2^{2^k}\) 种状态之一,那么设 \(F_{i,sta}\) 为用 \(i\) 个符号状态为 \(sta\) 的 \(Q\) 的数量。

\[F_{i,sta}=F_{i-1,\neg sta}+\sum\limits_{j+k=i-1,\neg s_1\lor s_2=sta} F_{j,s_1}\times F_{k,s_2}
\]

然后对于一个 \(P\) 暴力枚举 \(k\) 个变量的 \(2^k\) 种取值和 \(Q\) 的取值 \((0,1)\) 代入算一遍判断是否合法,这样就得到了对于 \(2^k\) 种变量的取值 \(Q\) 的限制 \(0\) 或 \(1\) 或 都可以。 那么再枚举 \(F\) 所对应的 \(2^{2^k}\) 种取值,将合法的取值加起来即可。

这样单次询问的复杂度为优秀的 \(O(2^{k+1}|P|+2^{2^k})\) ,此时复杂度瓶颈在于朴素 \(DP\) 预处理的 \(O(n^2\times 2^{2^{k+1}})\)

由于\(sta=\neg s_1\lor s_2\),\(i=j+k\),所以可以直接以 \(sta\) 为下标做 \(FWT\) 或卷积,并用 \(i\) 为下标做个背包,可以做到 \(O(n^2\times 2^k\times 2^{2^k})\)。

所以最终复杂度为\(O(n^2\times 2^k\times 2^{2^k}+m\times(2^{k+1}|P|+2^{2^k}))\)。

#include<bits/stdc++.h>
#define LL long long
#define M 65560
using namespace std;
int read(){
int nm=0,fh=1; char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
#define mod 1000000007
#define add(a,b) (((a)+(b))>=mod?((a)+(b)-mod):((a)+(b)))
#define mns(a,b) (((a)-(b))<0?((a)-(b)+mod):((a)-(b)))
#define mul(a,b) ((LL)(a)*(LL)(b)%mod)
void upd(int &x,int y){x=add(x,y);}
int n,m,len,F[72][M],G[72][M],maxn,LEN,S[M],top,st[M],tp,b[2]; char ch[4002];
void FWT(int *x,int kd){
for(int tt=1;tt<len;tt<<=1) for(int st=0;st<len;st+=(tt<<1)) for(int pos=st;pos<st+tt;pos++)
x[pos+tt]=((kd>0)?add(x[pos+tt],x[pos]):mns(x[pos+tt],x[pos]));
}
int op(int x,int y,int kd){return (kd==-3)?((!x)|y):(!y);}
int calc(int STA,int KD){
for(int i=1;i<=top;i++){
if(S[i]<-2) st[tp-1]=op(st[tp-1],st[tp],S[i]),tp--;
else if(S[i]==10) st[++tp]=KD; else if(S[i]==-2) st[++tp]=-2;
else st[++tp]=((STA>>S[i])&1);
} return st[(tp=0)+1];
}
bool IN(int x,int tot){return (x&tot)==x;}
int solve(){
scanf("%s",ch),LEN=strlen(ch),top=tp=0; int res=0;
for(int i=0;i<LEN;i++){
if(ch[i]=='(') st[++tp]=-1;
if(ch[i]=='x') S[++top]=ch[++i]-'1'; if(ch[i]=='Q'){S[++top]=10;}
if(ch[i]=='-'){for(i++;tp&&st[tp]<=-3;S[++top]=st[tp--]);st[++tp]=-3;}
if(ch[i]=='~'){S[++top]=-2; while(tp&&st[tp]<=-4) S[++top]=st[tp--];st[++tp]=-4;}
if(ch[i]==')'){while(tp&&st[tp]<=-3) S[++top]=st[tp--];tp--;}
} while(tp) S[++top]=st[tp--]; b[0]=b[1]=0;
for(int i=0;i<maxn;i++) for(int kd=0;kd<2;kd++) b[kd]|=(calc(i,kd)<<i);
for(int i=0;i<len;i++) if(IN(i,b[1])&&IN((len-1)^i,b[0])) upd(res,F[n][i]); return res;
}
int main(){
n=read(),m=read(),len=(1<<(maxn=(1<<m)));
for(int i=0,sta=0;i<m;i++,sta=0){
for(int now=0;now<maxn;now++) if((now>>i)&1) sta|=(1<<now); F[0][sta]++;
}
for(int i=0;i<len;i++) G[0][i]=F[0][(len-1)^i]; FWT(G[0],1),FWT(F[0],1);
for(int i=1;i<=n;i++){
memcpy(F[i],G[i-1],sizeof(F[i]));
for(int k=0;k<i;k++) for(int pos=0;pos<len;pos++)
upd(F[i][pos],mul(G[k][pos],F[i-k-1][pos]));
FWT(F[i],-1),memcpy(G[i],F[i],sizeof(G[i])),reverse(G[i],G[i]+len);
if(i<n) FWT(F[i],1),FWT(G[i],1);
}
for(int T=read();T;--T) printf("%d\n",solve()); return 0;
}

Proposition的更多相关文章

  1. HDU 5420 Victor and Proposition

    Victor and Proposition Time Limit: 6000ms Memory Limit: 524288KB This problem will be judged on HDU. ...

  2. Theorem、Proposition、Lemma和Corollary等的解释与区别

    Theorem:定理.是文章中重要的数学化的论述,一般有严格的数学证明. Proposition:可以翻译为命题,经过证明且interesting,但没有Theorem重要,比较常用. Lemma:一 ...

  3. Life Is A Funny Proposition After All

    你们有没有坐下思考,感到疑惑 ,静静思考,我们为什么在这里 ,生活为什么如此这般 这个问题让无数聪明人喝酒买醉,这是最最奇怪的事情,他们都想弄清楚,科学家们可以展示上千种不同的理论,但从未证明这是为什 ...

  4. BizDevOps — the true value proposition of workflow engines

    转自:https://blog.bernd-ruecker.com/bizdevops-the-true-value-proposition-of-workflow-engines-f342509ba ...

  5. HDU5420 : Victor and Proposition

    以深度建立线段树,线段树父亲节点向儿子节点连边,然后用线段树合并可以得到任何一个点子树的线段树,只需向对应节点的线段树中的$O(\log n)$个点连边即可.为了保证连边关系不发生混乱,线段树需要进行 ...

  6. <Sicily>Pythagorean Proposition

    一.题目描述 One day, WXYZ got a wooden stick, he wanted to split it into three sticks and make a right-an ...

  7. Java资源大全中文版(Awesome最新版)

    Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...

  8. 我的LaTeX中文文档模板

    中文LaTeX处理模板 环境MiTex内核 编辑环境WinEdit 源码如下: \documentclass[a4paper,12pt]{article} \usepackage{CJK} %设定字号 ...

  9. Introduction to Microsoft Dynamics 365 licensing

    Microsoft Dynamics 365 will be released on November 1. In preparation for that, Scott Guthrie hosted ...

随机推荐

  1. SqlHelper简单实现(通过Expression和反射)2.特性和实体设计

    对于需求中的不要暴露DataTable或DataSet,我想到了设计中常用的对象:实体(Entity),通过实体将数据库中的字段封装成类,这样做不仅使代码更有可读性,维护起来也很方便.同时我自定义了一 ...

  2. boot空间不足,删除Ubuntu旧内核

    0 Problem 今天打开电脑的时候ubuntu提示boot空间不足.查了资料,原来Ubuntu的自动升级并没有删除系统的旧内核,于是boot下旧的内核文件越积越多,最后就满了. 1 Solutio ...

  3. 《TCP/IP详解:卷一》-TCP部分讲解

    TCP/IP协议 作者:Danbo 2015-7-2 本文为参考TCP/IP详解卷一,某些知识点加上了作者自己的理解,如有错误,欢迎指正,可以微博联系我! TCP包格式和IP包格式如下: TCP的正常 ...

  4. SVN使用—高级用法

    一.SVN分支 Branch 选项会给开发者创建出另外一条线路.当有人希望开发进程分开成两条不同的线路时,这个选项会非常有用. 情景: 比如项目 demo 下有两个小组,svn 下有一个 trunk ...

  5. 20162326 齐力锋 2016-2017-2 《程序设计与数据结构》 MySort.java 实验博客

    实验代码学习编程中的问题及解决方法 代码运行成功截图 首次代码运行出现的问题截图 问题1:无法从静态上下文中引用非静态方法 问题1解决方法及思考: split方法是非静态方法,需要借助对象来调用.我查 ...

  6. 2062326 齐力锋 实验二《Java面向对象程序设计》实验报告

    北京电子科技学院(BESTI) 实     验    报     告 课程:   程序设计与数据结构           班级:      1623           姓名:  齐力锋      学 ...

  7. eclipse中的错误解决——Servlet cannot be resolved to a type

    问题如图 解决问题方法

  8. java 处理emoji表情信息转换为String

    2种方式实现: 注意:如果发现运行时java.lang.NoClassDefFoundError:异常就是缺少了jar包.添加对应的jar包就可以. 一.emoji-java-4.0.0.jar实现 ...

  9. JavaScript 打印控件

    JavaScript 打印控件 github地址 https://github.com/DoersGuild/jQuery.print 使用前需要引入jQuery $("#mapDiv&qu ...

  10. Mac系统下安装ipython分别支持python2和python3

    操作系统:Mac10.11.5 python2.7.13 python3.6.1 安装python2: brew install python 安装python3: brew install pyth ...