Proposition



提供 \(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\) 的数量。
\]
然后对于一个 \(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的更多相关文章
- HDU 5420 Victor and Proposition
Victor and Proposition Time Limit: 6000ms Memory Limit: 524288KB This problem will be judged on HDU. ...
- Theorem、Proposition、Lemma和Corollary等的解释与区别
Theorem:定理.是文章中重要的数学化的论述,一般有严格的数学证明. Proposition:可以翻译为命题,经过证明且interesting,但没有Theorem重要,比较常用. Lemma:一 ...
- Life Is A Funny Proposition After All
你们有没有坐下思考,感到疑惑 ,静静思考,我们为什么在这里 ,生活为什么如此这般 这个问题让无数聪明人喝酒买醉,这是最最奇怪的事情,他们都想弄清楚,科学家们可以展示上千种不同的理论,但从未证明这是为什 ...
- BizDevOps — the true value proposition of workflow engines
转自:https://blog.bernd-ruecker.com/bizdevops-the-true-value-proposition-of-workflow-engines-f342509ba ...
- HDU5420 : Victor and Proposition
以深度建立线段树,线段树父亲节点向儿子节点连边,然后用线段树合并可以得到任何一个点子树的线段树,只需向对应节点的线段树中的$O(\log n)$个点连边即可.为了保证连边关系不发生混乱,线段树需要进行 ...
- <Sicily>Pythagorean Proposition
一.题目描述 One day, WXYZ got a wooden stick, he wanted to split it into three sticks and make a right-an ...
- Java资源大全中文版(Awesome最新版)
Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...
- 我的LaTeX中文文档模板
中文LaTeX处理模板 环境MiTex内核 编辑环境WinEdit 源码如下: \documentclass[a4paper,12pt]{article} \usepackage{CJK} %设定字号 ...
- Introduction to Microsoft Dynamics 365 licensing
Microsoft Dynamics 365 will be released on November 1. In preparation for that, Scott Guthrie hosted ...
随机推荐
- SVN插件下载地址及更新地址
SVN插件下载地址及更新地址,你根据需要选择你需要的版本.现在最新是1.8.xLinks for 1.8.x Release:Eclipse update site URL: http://subcl ...
- MapReduce概述
MapReduce 源自于Google的MapReduce论文,Hadoop MapReduce是Google MapReduce克隆版 MapReduce适合PB级以上海量数据的离线处理 MapRe ...
- 轮询、长轮询、长连接、socket连接、WebSocket
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源.(而每一次的 HTTP 请求和应答 ...
- 深入理解JVM 垃圾收集器(下)G1收集器
1.回顾CMS 1.1堆内存结构 1.2新生代GC 1.3老年代GC 2.G1收集器 2.1G1实现概览及使用场景 G1的推荐使用场景 2.2GC 2.2.1新生代GC 2.2.2老年代GC 老年代G ...
- Mysql 基本用法
Java中两种常用的数据库: MYSQL Oracle MYSQL :开源免费的数据库,小型的数据库.由瑞典MySQL AB 公司开发,适合中小企业使用,由C语言和C++编写的.已经被Ora ...
- PHP设计模式(一):简单工厂模式
- LINUX系统运行查看
1.查看内存使用情况 free -m 2.查看内存,cpu等使用情况排序,使用ps -aux命令 ps -aux --sort=+rss :按内存升序排列 ps -aux --sort=-rss :按 ...
- 关于阿里云Symantec免费DV证书部署HTTPS
获取阿里云Symantec免费DV证书: 官方文件说明: 证书文件214188487290026.pem,包含两段内容,请不要删除任何一段内容. 如果是证书系统创建的CSR,还包含:证书私钥文件214 ...
- spring通知的注解
1.代理类接口Person.java package com.xiaostudy; /** * @desc 被代理类接口 * * @author xiaostudy * */ public inter ...
- 使用nagios检测windows服务器
1.安装nagios windows客户端 下载NSClient++的安装包,注意根据实际的32/64CPU来下载 下载地址 http://sourceforge.net/projects/nscpl ...