2348-Testing Circuits

問題概要

論理式が与えられる.この式を満たすような変数の値の組み合わせの数を求めよ.ただし,同じ変数は一度しか表われない.

解法

構文解析する.スタックオーバーフローに注意する.

実装(C++)

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef unsigned char uchar;
typedef unsigned long long ull;
#define REP(i,x) for(long long i=0;i<(long long)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(long long i=(x);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)

template<typename T>
ostream &operator<<(ostream &os,vector<T> &a){
	copy(a.begin(),a.end(),ostream_iterator<T>(os," "));
	os<<endl;
	return os;
}
char *s;
typedef pair<long long,long long> P;
P expression();
P term();
P factor();
long long moduler(long long k){
	return k%1000000007;
	       //1000000007.
}
P ord(P a,P b){
	return P(moduler((long long)b.first*a.second+(long long)a.first*b.second+(long long)a.first*b.first),moduler((long long)a.second*b.second));
}
P notd(P a){
	return P(moduler(a.second),moduler(a.first));
}
struct S{
	P now;
	long long back;
};
stack<S>sta;
void solve(){
	P result;
	P now;
	S tmp;
	long long t;
	expr:
	tmp.now=now;
	tmp.back=0;
	sta.push(tmp);
	goto term;
	back_0:
	now=result;
	while((*s)=='|'){
		s++;
		tmp.now=now;
		tmp.back=1;
		sta.push(tmp);
		goto term;
		back_1:
		now=ord(now,result);
	}
	if(sta.empty()){
		cout<<now.first<<endl;
		return;
	}else{
		result=now;
		goto __back;
	}
	term:

	tmp.now=now;
	tmp.back=2;
	sta.push(tmp);
	goto factor;
	back_2:
	now=result;
	loop2:
	if(*s!='&')goto exit_loop2;

	s++;
	tmp.now=now;
	tmp.back=3;
	sta.push(tmp);
	goto factor;
	back_3:
	now=notd(ord(notd(now),notd(result)));
	goto loop2;
	exit_loop2:
	result=now;
	goto __back;
	factor:
	now=P(0,0);
	while(*s=='~'){
		now.first=!now.first;
		s++;
	}
	if(*s=='('){
		s++;
		tmp.now=now;
		tmp.back=4;
		sta.push(tmp);
		goto expr;
		back_4:
		s++;
		result=now.first?notd(result):(result);
		goto __back;
	}
	s++;
	result=P(1,1);
	goto __back;
	__back:
	t=sta.top().back;
	now=sta.top().now;
	sta.pop();
	if(t==0){
		goto back_0;
	}else if(t==1){
		goto back_1;
	}else if(t==2){
		goto back_2;
	}else if(t==3){
		goto back_3;
	}else if(t==4){
		goto back_4;
	}
}

char tmp[1111111];
char is[1111111];
int main(){
	cin >> is;
	long long now=0;
	for(long long i=0;is[i];i++){
		if(isdigit(is[i]))continue;
		tmp[now++]=is[i];
	}
	now=0;
	memset(is,0,sizeof(is));
	for(long long i=0;tmp[i];i++){
		is[i]=tmp[i];
	}
	s=is;

	solve();
}