表达式(exp)

题目大意

给定一个逻辑表达式,求每一个数满足$\in[1,n]$的使的表达式为真的方案数。

 

题解

题目限制较奇怪且数据范围较小,所以可以考虑直接暴力。

考虑枚举每一个变量一共出现了$k$种数值,再枚举这些数值之间的大小关系,判断是否满足表达式为真的条件,每有一种,答案就$+C_n^k$即可。

为了方便计算应把中缀表达式转化为后缀表达式,具体方法不再赘述。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define mod 1000000007
#define M 1020
#define OR -1
#define AND -2
#define LESS -3
using namespace std;
int read(){
	int nm=0,fh=1; int cw=getchar();
	for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
	for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
	return nm*fh;
}
int mul(int x,int y){return (LL)x*(LL)y%mod;}
int add(int x,int y){return (x+y)>=mod?(x+y-mod):x+y;}
int n,m,V[M],W[M],K[M],tot,C[M],p[M],top,S[M],ans;
void upd(int x){ans=add(ans,x);}
int calc(int m1,int m2,int kd){
	if(kd==OR) return m1||m2;
	if(kd==AND) return m1&&m2;
	return W[K[m1]]<W[K[m2]];
}
int qpow(int x,int sq){
	int res=1;
	for(;sq;x=mul(x,x),sq>>=1) if(sq&1) res=mul(res,x);
	return res;
}
void getans(int num){
	for(int i=1;i<=tot;W[i]=i,i++);
	do{
		top=0;
		for(int i=1;i<=n;i++){
			if(p[i]>0) S[++top]=p[i];
			else --top,S[top]=calc(S[top],S[top+1],p[i]);
		} if(S[top]) upd(num); --top;
	}while(next_permutation(W+1,W+tot+1));
}
void fd(int x){
	if(x==8){getans(C[tot]);return;}
	for(int i=1;i<=tot;i++){K[x]=i;fd(x+1);}
	K[x]=++tot,fd(x+1),tot--;
}
int main(){
	for(int ch=getchar();ch!='\n';ch=getchar()){
		if(ch==' ') continue;
		if(islower(ch)) p[++n]=ch-'a'+1; if(ch=='(') S[++top]=9;
		if(ch==')'){while(S[top--]!=9) p[++n]=S[top+1];}
		if(ch=='<'){while(S[top]<=LESS) p[++n]=S[top--];S[++top]=LESS;}
		if(ch=='&'){while(S[top]<=AND) p[++n]=S[top--];S[++top]=AND;}
		if(ch=='|'){while(S[top]<=OR) p[++n]=S[top--];S[++top]=OR;}
	} while(top) p[++n]=S[top--]; m=read(),C[0]=1;
	for(int i=1;i<=n;i++){
		if(p[i]>0) putchar('a'-1+p[i]);
		else if(p[i]==LESS) putchar('<');
		else if(p[i]==OR) putchar('|');
		else if(p[i]==AND) putchar('&');
		else puts("SJK_AK_IOI");
		putchar(i<n?' ':'\n');
	}
	for(int i=1;i<=7;i++) C[i]=mul(C[i-1],mul(qpow(i,mod-2),m-i+1));
	fd(1),printf("%d\n",ans);return 0;
}

 

posted @ 2018-10-15 21:38  OYJason  阅读(814)  评论(0编辑  收藏  举报