输出两行,第一行包含一个只有0、1、&、|和^组成的字符串。其长度小于500,第二行只有一个布尔值,代表desired。
输出一个整数,表示取模后的答案。
1^0|0|1 false
2
1^((0|0)|1)和1^(0|(0|1))可以得到false
1 false
0
时间复杂度,空间复杂度
。
public class Main {
public static void main(String[] args) {
String inputString;
boolean desires;
long[][] trueMatrix; // trueMatrix[i][j]表示从i到j的子串要得到true有多少种组合
long[][] falseMatrix;
final long A = 1000000007;
// 获取输入
java.util.Scanner input = new java.util.Scanner(System.in);
inputString = input.nextLine();
desires = input.nextBoolean();
int length = inputString.length();
trueMatrix = new long[length][length];
falseMatrix = new long[length][length];
// 先处理长度为1的子串
for (int i = 0; i < length; i += 2) {
char c = inputString.charAt(i);
if (c == '1') {
trueMatrix[i][i] = 1;
falseMatrix[i][i] = 0;
} else if (c == '0'){
trueMatrix[i][i] = 0;
falseMatrix[i][i] = 1;
} else {
// 如果输入无效就直接返回
System.out.println(0);
return;
}
}
// 从长度为3的子串开始,每次递增2,一直处理到长度为length
for (int subLen = 3; subLen <= length; subLen += 2) {
// 处理所有长度为subLen的子串,从开头为0的子串开始,每次递增2
for (int start = 0; start + subLen <= length; start += 2) {
// 遍历子串中的所有运算符,对每一个运算符求出组合种数,累加到matirx[start][start + subLen -1]上
for (int mid = start + 1; mid < start + subLen; mid += 2) {
char c = inputString.charAt(mid);
// 先得到左真,左假,右真,右假,对每种运算符都要用到这四个值
long leftTrue = trueMatrix[start][mid - 1];
long leftFalse = falseMatrix[start][mid - 1];
long rightTrue = trueMatrix[mid + 1][start + subLen - 1];
long rightFalse = falseMatrix[mid + 1][start + subLen - 1];
if (c == '&') {
// 对于&,要想得到真,左右都是真
trueMatrix[start][start + subLen - 1] += ((leftTrue * rightTrue) % A);
// 要想得到假,左右至少有一个为假
falseMatrix[start][start + subLen - 1] += ((leftFalse * rightTrue) % A)
+ ((leftTrue * rightFalse) % A) + ((leftFalse * rightFalse) % A);
} else if (c == '|') {
// 对于|,想要得到真,左右至少有一个为真
trueMatrix[start][start + subLen - 1] += ((leftTrue * rightTrue) % A)
+ ((leftFalse * rightTrue) % A) + ((leftTrue * rightFalse) % A);
// 要想得到假,左右都是假
falseMatrix[start][start + subLen - 1] += ((leftFalse * rightFalse) % A);
} else if (c == '^') {
// 对于^,要想得到真,左真又假,或者左假右真
trueMatrix[start][start + subLen - 1] += ((leftTrue * rightFalse) % A)
+ ((leftFalse * rightTrue) % A);
// 要想得到假,左右都为真或者假
falseMatrix[start][start + subLen - 1] += ((leftTrue * rightTrue) % A)
+ ((leftFalse * rightFalse) % A);
} else {
// 如果输入不规范就直接返回
System.out.println(0);
return;
}
trueMatrix[start][start + subLen - 1] %= A;
falseMatrix[start][start + subLen - 1] %= A;
}
}
}
// 输出结果
if (desires) {
System.out.println(trueMatrix[0][length - 1]);
}
else {
System.out.println((falseMatrix[0][length - 1]));
}
}
}
/*
* @Author: RockyHoo
* @Date: 2022-03-15 11:29:54
* @LastEditTime: 2022-03-15 15:27:26
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \DP\Untitled1.cpp
*/
#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
const int maxn=507;
void dfs(string s,int start,int end,long long (*dp_true)[maxn],long long (*dp_false)[maxn]){
if(end-start<0) return;
if(end-start==0){
if(s[start]=='1') dp_true[start][start]=1,dp_false[start][start]=0;
else if(s[start]=='0') dp_false[start][start]=1,dp_true[start][start]=0;
return;
}
int next_sybol_pos=start+1;
for(int i=next_sybol_pos;i<end;i+=2){
if(s[i]=='^'){
if(dp_true[start][i-1]==-1) dfs(s,start,i-1,dp_true,dp_false);
if(dp_false[i+1][end]==-1) dfs(s,i+1,end,dp_true,dp_false);
if( dp_true[start][end]==-1) dp_true[start][end]=0;
if(dp_false[start][end]==-1) dp_false[start][end]=0;
dp_true[start][end]+=((dp_true[start][i-1]*dp_false[i+1][end])%mod+(dp_false[start][i-1]*dp_true[i+1][end])%mod)%mod;
dp_false[start][end]+=((dp_true[start][i-1]*dp_true[i+1][end])%mod+(dp_false[start][i-1]*dp_false[i+1][end])%mod)%mod;
// cout<<"^"<<"i:"<<i<<" start:"<<start<<" end:"<<end<<" dp_true:"<<dp_true[start][end]<<" dp_false:"<<dp_false[start][end]<<endl;
}else if(s[i]=='|'){
if(dp_true[start][i-1]==-1) dfs(s,start,i-1,dp_true,dp_false);
if(dp_false[i+1][end]==-1) dfs(s,i+1,end,dp_true,dp_false);
if( dp_true[start][end]==-1) dp_true[start][end]=0;
if(dp_false[start][end]==-1) dp_false[start][end]=0;
dp_true[start][end]+=((dp_true[start][i-1]*dp_false[i+1][end])%mod+(dp_false[start][i-1]*dp_true[i+1][end])%mod+(dp_true[start][i-1]*dp_true[i+1][end])%mod)%mod;
dp_false[start][end]+=(dp_false[start][i-1]*dp_false[i+1][end])%mod;
// cout<<"|"<<"i:"<<i<<" start:"<<start<<" end:"<<end<<" dp_true:"<<dp_true[start][end]<<" dp_false:"<<dp_false[start][end]<<endl;
}else if(s[i]=='&'){
if(dp_true[start][i-1]==-1) dfs(s,start,i-1,dp_true,dp_false);
if(dp_false[i+1][end]==-1) dfs(s,i+1,end,dp_true,dp_false);
if( dp_true[start][end]==-1) dp_true[start][end]=0;
if(dp_false[start][end]==-1) dp_false[start][end]=0;
dp_true[start][end]+=(dp_true[start][i-1]*dp_true[i+1][end])%mod;
dp_false[start][end]+=((dp_false[start][i-1]*dp_true[i+1][end])%mod+(dp_false[start][i-1]*dp_false[i+1][end])%mod+(dp_true[start][i-1]*dp_false[i+1][end])%mod)%mod;
// cout<<"&"<<"i:"<<i<<" start:"<<start<<" end:"<<end<<" dp_true:"<<dp_true[start][end]<<" dp_false:"<<dp_false[start][end]<<endl;
}
dp_true[start][end]%=mod;
dp_false[start][end]%=mod;
}
}
int main(){
string s,desire;
long long dp_true[maxn][maxn],dp_false[maxn][maxn];
while(cin>>s){
cin>>desire;
memset(dp_true,-1,sizeof(dp_true));
memset(dp_false,-1,sizeof(dp_false));
int n=s.size()-1;
dfs(s,0,n,dp_true,dp_false);
if(desire=="true"){
printf("%lld\n",dp_true[0][n]%mod<0?0:dp_true[0][n]%mod);
}else{
printf("%lld\n",dp_false[0][n]%mod<0?0:dp_false[0][n]%mod);
}
}
return 0;
}
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdbool.h>
#define MOD 1000000007
typedef unsigned long long ull;
bool isValid(char *exp, int len) {
if (len % 2 == 0) {
return false;
}
for (int i = 0; i < len; i += 2) {
if (exp[i] != '0' && exp[i] != '1') {
return false;
}
}
for (int i = 1; i < len; i += 2) {
if (exp[i] != '&' && exp[i] != '|' && exp[i] != '^') {
return false;
}
}
return true;
}
int main(void) {
char exp[501], desStr[6];
int len;
bool des;
scanf("%s%s", exp, desStr);
len = strlen(exp);
des = strcmp(desStr, "true") == 0;
if (!isValid(exp, len)) {
printf("0\n");
return 0;
}
ull **t, **f;
t = (ull **) malloc(sizeof(ull *) * len);
f = (ull **) malloc(sizeof(ull *) * len);
for (int i = 0; i < len; i++) {
t[i] = (ull *) calloc(len, sizeof(ull));
f[i] = (ull *) calloc(len, sizeof(ull));
}
t[0][0] = exp[0] == '1' ? 1 : 0;
f[0][0] = exp[0] == '0' ? 1 : 0;
for (int i = 2; i < len; i += 2) {
t[i][i] = exp[i] == '1' ? 1 : 0;
f[i][i] = exp[i] == '0' ? 1 : 0;
for (int j = i - 2; j >= 0; j -= 2) {
for (int k = j; k < i; k += 2) {
if (exp[k + 1] == '&') {
t[j][i] = (t[j][i] + (t[j][k] * t[k + 2][i]) % MOD) % MOD;
f[j][i] = (f[j][i] + (t[j][k] * f[k + 2][i]) % MOD) % MOD;
f[j][i] = (f[j][i] + (f[j][k] * t[k + 2][i]) % MOD) % MOD;
f[j][i] = (f[j][i] + (f[j][k] * f[k + 2][i]) % MOD) % MOD;
} else if (exp[k + 1] == '|') {
t[j][i] = (t[j][i] + (t[j][k] * f[k + 2][i]) % MOD) % MOD;
t[j][i] = (t[j][i] + (f[j][k] * t[k + 2][i]) % MOD) % MOD;
t[j][i] = (t[j][i] + (t[j][k] * t[k + 2][i]) % MOD) % MOD;
f[j][i] = (f[j][i] + (f[j][k] * f[k + 2][i]) % MOD) % MOD;
} else {
t[j][i] = (t[j][i] + (t[j][k] * f[k + 2][i]) % MOD) % MOD;
t[j][i] = (t[j][i] + (f[j][k] * t[k + 2][i]) % MOD) % MOD;
f[j][i] = (f[j][i] + (t[j][k] * t[k + 2][i]) % MOD) % MOD;
f[j][i] = (f[j][i] + (f[j][k] * f[k + 2][i]) % MOD) % MOD;
}
}
}
}
printf("%llu\n", des ? t[0][len - 1] : f[0][len - 1]);
return 0;
} import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
static final int MOD = 1000000007;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] express = br.readLine().toCharArray();
boolean desired = Boolean.valueOf(br.readLine()).booleanValue();
System.out.println(solve(express, desired));
}
private static int solve(char[] express, boolean desired) {
if(!isValid(express)){
return 0;
}
return (int)dynamicProgramming(express, desired);
}
private static long dynamicProgramming(char[] express, boolean desired) {
long[][] t = new long[express.length][express.length]; // t[i][j]表示express[i:j]上为true时的方案数
long[][] f = new long[express.length][express.length]; // f[i][j]表示express[i:j]上为false时的方案数
// base case区间上只有一个字符时的可能性
for(int i = 0; i < express.length; i += 2){
t[i][i] = express[i] == '1'? 1: 0;
f[i][i] = express[i] == '0'? 1: 0;
}
for(int right = 2; right < express.length; right += 2){
for(int left = right - 2; left >= 0; left -= 2){
// 假设k位置为左部分最后一个数
for(int k = left; k < right; k += 2){
if(express[k + 1] == '&'){
// 要得到true需要两边都是true
t[left][right] += ((t[left][k]*t[k + 2][right]) % MOD) % MOD;
t[left][right] %= MOD;
// 要得到false需要两边至少有一个false
f[left][right] += ((t[left][k]*f[k + 2][right]) % MOD + (f[left][k]*t[k + 2][right]) % MOD + (f[left][k]*f[k + 2][right]) % MOD) % MOD;
f[left][right] %= MOD;
}else if(express[k + 1] == '|'){
// 要得到true需要两边至少有一个true
t[left][right] += ((f[left][k]*t[k + 2][right]) % MOD + (t[left][k]*f[k + 2][right]) % MOD + (t[left][k]*t[k + 2][right]) % MOD) % MOD;
t[left][right] %= MOD;
// 要得到false需要两边都是false
f[left][right] += ((f[left][k]*f[k + 2][right]) % MOD) % MOD;
f[left][right] %= MOD;
}else{
// 要得到true需要两边不同
t[left][right] += ((f[left][k]*t[k + 2][right]) % MOD + (t[left][k]*f[k + 2][right]) % MOD) % MOD;
t[left][right] %= MOD;
// 要得到false需要两边相同
f[left][right] += ((t[left][k]*t[k + 2][right]) % MOD + (f[left][k]*f[k + 2][right]) % MOD) % MOD;
f[left][right] %= MOD;
}
}
}
}
return desired? t[0][express.length - 1]: f[0][express.length - 1];
}
// 检查表达式的合法性
private static boolean isValid(char[] express) {
if(express == null || (express.length & 1) == 0){
return false;
}
for(int i = 0; i < express.length; i += 2){
if(express[i] != '0' && express[i] != '1'){
return false;
}
}
for(int i = 1; i < express.length; i += 2){
if(express[i] != '&' && express[i] != '|' && express[i] != '^'){
return false;
}
}
return true;
}
} 本题为了稳,仍然可以采用先写暴力递归,再将暴力递归改写成动态规划的方式,这里我直接提供一个动态规划的版本。不得不说的是,这个题的用例实在是太魔性了,我取这么多次余最终也逃脱不了用long类型的命运/*
*动态规划
*应有dp_true和dp_false两个表
*如dp_true[1,2]代表了, 从字符串第1个数字到第2个数字,有多少种组合可以为true
*那么本题的答案就应该是desired(为true或false)dp_*[1][n]
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string s;
vector<vector<long long int>> dp_true,dp_false;
long long int A = 1000000007;
long long int dp(int l,int r,bool b){
if(l==r){
if(b==true){
if(s[l]=='1'){
if(dp_true[l][r]==-1) dp_true[l][r]=1;
return 1;
}
else{
if(dp_true[l][r]==-1) dp_true[l][r]=0;
return 0;
}
}
else{
if(s[l]=='0'){
if(dp_false[l][r]==-1) dp_false[l][r]=1;
return 1;
}
else {
if(dp_false[l][r]==-1) dp_false[l][r]=0;
return 0;
}
}
}
long long int ans=0;
if(b==true){
if(dp_true[l][r]!=-1){
return dp_true[l][r];
}
for(int i=l;i<r;i++){
if(isdigit(s[i])){
i++;
}
if(s[i]=='^'){
ans+=((dp(l,i-1,true)*dp(i+1,r,false)+dp(l,i-1,false)*dp(i+1,r,true))%A);
}
else if(s[i]=='|'){
ans+=((dp(l,i-1,true)*dp(i+1,r,false)+dp(l,i-1,false)*dp(i+1,r,true)+dp(l,i-1,true)*dp(i+1,r,true))%A);
}
else if(s[i]=='&'){
ans+=((dp(l,i-1,true)*dp(i+1,r,true))%A);
}
}
//如果dp数组还不存在要储存一下
if(dp_true[l][r]==-1){
dp_true[l][r]=ans%A;
}
return ans%A;
}
//如果b是false的情况
else{
//如果dp数组已知直接返回
if(dp_false[l][r]!=-1){
return dp_false[l][r];
}
for(int i=l;i<r;i++){
if(isdigit(s[i])){
i++;
}
if(s[i]=='^'){
ans+=((dp(l,i-1,true)*dp(i+1,r,true)+dp(l,i-1,false)*dp(i+1,r,false))%A);
}
else if(s[i]=='|'){
ans+=((dp(l,i-1,false)*dp(i+1,r,false))%A);
}
else if(s[i]=='&'){
ans+=((dp(l,i-1,true)*dp(i+1,r,false)+dp(l,i-1,false)*dp(i+1,r,true)+dp(l,i-1,false)*dp(i+1,r,false))%A);
}
}
if(dp_false[l][r]==-1){
dp_false[l][r]=ans%A;
}
return ans%A;
}
}
int main(){
cin>>s;
int n=s.size();
dp_true.resize(n,vector<long long int> (n,-1));
dp_false.resize(n,vector<long long int> (n,-1));
bool desired;
cin>>desired;
cout<<dp(0,n-1,desired);
return 0;
} 最后只能通过70%算例,有没有同学解答下为什么……😪
#include<iostream>
using namespace std;
bool valid(string &s) {
if( s.size() & 1 ) {
int n = s.size();
for(int i=0; i<n; i+=2) {
if(s[i]!='1' && s[i] !='0') return false;
}
for(int i=1; i<n; i+=2) {
if(s[i]=='^' || s[i]=='|' || s[i] =='&') continue;
else return false;
}
return true;
}
return false;
}
int p(string &s,bool expected, int l,int r) {
if(l==r) {
if(s[l]=='1') return expected? 1:0;
else return expected? 0:1;
}
int res = 0;
if(expected) {
for(int i=l+1;i<r;i+=2) {
switch(s[i]) {
case '&':{
res += p(s,true,l,i-1)*p(s,true,i+1,r);
break;
}
case '|':{
res += p(s,true,l,i-1 )*p(s,false,i+1,r);
res += p(s,false,l,i-1)*p(s,true,i+1,r);
res += p(s,true,l,i-1 )*p(s,true,i+1,r);
break;
}
case '^':{
res += p(s,true,l,i-1)*p(s,false,i+1,r);
res += p(s,false,l,i-1)*p(s,true,i+1,r);
break;
}
}
}
}else {
for(int i=l+1;i<r;i+=2) {
switch(s[i]) {
case '&':{
res += p(s,false,l,i-1)*p(s,true,i+1,r);
res += p(s,true,l,i-1)*p(s,false,i+1,r);
res += p(s,false,l,i-1)*p(s,false,i+1,r);
break;
}
case '|':{
res += p(s,false,l,i-1)*p(s,false,i+1,r);
break;
}
case '^':{
res += p(s,true,l,i-1)*p(s,true,i+1,r);
res += p(s,false,l,i-1)*p(s,false,i+1,r);
break;
}
}
}
}
return res;
}
int main() {
string s,ress;
bool expected;
cin>>s>>ress;
expected = ress == "true";
if(valid(s)==false ) {
puts("0");
return 0;
}
cout << p(s,expected,0 ,s.size()-1);
return 0;
}
bool isValid(const string& exp)
{
if(exp.size()&1==0)
return false;
for(int indx=0;indx<exp.size();indx+=2)
{
if(exp[indx]!='0'&&exp[indx]!='1')
return false;
}
for(int indx=1;indx<exp.size();indx+=2)
{
if(exp[indx]!='&'&&exp[indx]!='|'&&exp[indx]!='^')
return false;
}
return true;
}
int main()
{
const int mod=1000000007;
string s;
bool flag;
cin>>s>>flag;
int len=s.size();
if(len%2==0)
{
cout<<0<<endl;
return 0;
}
if(!isValid(s))
{
cout<<0<<endl;
return 0;
}
int l1=(len+1)/2; //数字的数量
int l2=len-l1;//符号的数量
vector<char> arr2(l2);//arr[i]=k k=0表示& k=1表示| k=2表示^
vector<vector<unsigned long long>> dp_true(l1,vector<unsigned long long>(l1,0)); //dp_true[i][j]=k 表示从数字i到数字j 可以组合的true数量
vector<vector<unsigned long long>> dp_false(l1,vector<unsigned long long>(l1,0));
for(int i=0;i<len;i++)
{
if(i%2==0)
{
if(s[i]!='0' && s[i]!='1')
{
cout<<0<<endl;
return 0;
}
dp_true[i/2][i/2]=(s[i]=='1'?1:0);
dp_false[i/2][i/2]=(s[i]=='0'?1:0);
}
else
arr2[i/2]=s[i];
}
for(int len=2;len<=l1;len++) //采取先计算小区间=》后计算大区间
for(int i=0;i+len<=l1;i++)
{
int j=i+len-1; //区间终点 j
for(int k=i;k<j;k++) //研究最后计算的那个符号
{
if(arr2[k]=='&')
{
dp_true[i][j]=(dp_true[i][j]+dp_true[i][k]*dp_true[k+1][j])%1000000007;//为真的情况 只能是两边都为真
dp_false[i][j]=(dp_false[i][j]+dp_false[i][k]*(dp_true[k+1][j]+dp_false[k+1][j])+dp_true[i][k]*dp_false[k+1][j])%1000000007;//前面为假
}
else if(arr2[k]=='|')
{
dp_false[i][j]=(dp_false[i][j]+dp_false[i][k]*dp_false[k+1][j])%1000000007;//为假的情况 只能是两边都为假
dp_true[i][j]=(dp_true[i][j]+dp_true[i][k]*(dp_true[k+1][j]+dp_false[k+1][j])+dp_false[i][k]*dp_true[k+1][j])%1000000007;//前面为真
}
else
{
dp_true[i][j]=(dp_true[i][j]+dp_true[i][k]*dp_false[k+1][j]+dp_false[i][k]*dp_true[k+1][j])%1000000007;
dp_false[i][j]=(dp_false[i][j]+dp_true[i][k]*dp_true[k+1][j]+dp_false[i][k]*dp_false[k+1][j])%1000000007;
}
}
}
if(flag)
cout<<dp_true[0][l1-1]<<endl;
else
cout<<dp_false[0][l1-1]<<endl;
} private static long func(String opt, boolean flag) {
if (opt == null || opt == "" || isValid(opt) == false)
return 0;
int intLength = opt.length() / 2;
long[][] T = new long[intLength + 1][intLength + 1]; //true
long[][] F = new long[intLength + 1][intLength + 1]; // false
char[] opts = new char[intLength]; // 记录操作符&| opts[i]对应的是ints[i]后面跟的操作数
int[] ints = new int[intLength + 1]; // 记录被操作的数字
for (int i = 0, j = 0; i < opt.length(); i += 2, j++) {
ints[j] = opt.charAt(i) == '1' ? 1 : 0; //填充操作数
}
for (int i = 1, j = 0; i < opt.length(); i += 2, j++) {
opts[j] = opt.charAt(i); // 填充字符
}
for (int i = ints.length - 1; i >= 0; i--) {
T[i][i] = ints[i] == 0 ? 0 : 1;
F[i][i] = ints[i] == 0 ? 1 : 0;
for (int j = i + 1; j < ints.length; j++) {
for (int k = i; k < j; k++) {
switch (opts[k]) {
case '^':
T[i][j] = (T[i][j] + T[i][k] * F[k + 1][j] % X + F[i][k] * T[k + 1][j] % X) % X;
F[i][j] = (F[i][j] + T[i][k] * T[k + 1][j] % X + F[i][k] * F[k + 1][j] % X) % X;
break;
case '|':
T[i][j] = (T[i][j] + T[i][k] * T[k + 1][j] % X + T[i][k] * F[k + 1][j] % X + F[i][k] * T[k + 1][j] % X) % X;
F[i][j] = (F[i][j] + F[i][k] * F[k + 1][j] % X) % X;
break;
case '&':
T[i][j] = (T[i][j] + T[i][k] * T[k + 1][j] % X) % X;
F[i][j] = (F[i][j] + T[i][k] * F[k + 1][j] % X + F[i][k] * T[k + 1][j] % X + F[i][k] * F[k + 1][j] % X) % X;
break;
}
}
}
}
return flag ? T[0][T.length - 1] : F[0][F.length - 1];
} 1^0|0|1探索规律:
import java.util.*;
public class Main {
public static long mod = 1_000_000_007;
public boolean isValid(char[] exp) {
if (exp.length % 2 == 0) return false;
for (int i = 0; i < exp.length; i += 2) {
if (exp[i] != '0' && exp[i] != '1')
return false;
}
for (int i = 1; i < exp.length; i += 2) {
if (exp[i] != '^' && exp[i] != '&' && exp[i] != '|')
return false;
}
return true;
}
public long num(String express, boolean desired) {
if (express == null || express.equals("")) return 0;
char[] exp = express.toCharArray();
if (!isValid(exp)) return 0;
long [][] t = new long[exp.length][exp.length];
long [][] f = new long[exp.length][exp.length];
for (int i = 0; i < exp.length; i += 2) {
t[i][i] = exp[i] == '1' ? 1 : 0;
f[i][i] = exp[i] == '0' ? 1 : 0;
}
for (int i = 2; i < exp.length; i += 2) {
for (int j = 0; j < exp.length - i; j += 2) {
// j ... i+j
t[j][i + j] = 0;
f[j][i + j] = 0;
for (int k = 0; k < i; k += 2) {
if (exp[j + k + 1] == '^') {
t[j][i + j] += ((t[j][j + k] * f[j + k + 2][i + j]) % mod + (f[j][j + k] * t[j + k + 2][i + j]) % mod) % mod;
t[j][i + j] %= mod;
f[j][i + j] += ((t[j][j + k] * t[j + k + 2][i + j]) % mod + (f[j][j + k] * f[j + k + 2][i + j]) % mod) % mod;
f[j][i + j] %= mod;
} else if (exp[j + k + 1] == '&') {
t[j][i + j] += ((t[j][j + k] * t[j + k + 2][i + j]) % mod) % mod;
t[j][i + j] %= mod;
f[j][i + j] += ((t[j][j + k] * f[j + k + 2][i + j]) % mod + (f[j][j + k] * t[j + k + 2][i + j]) % mod + (f[j][j + k] * f[j + k + 2][i + j]) % mod) % mod;
f[j][i + j] %= mod;
} else if (exp[j + k + 1] == '|') {
t[j][i + j] += ((t[j][j + k] * f[j + k + 2][i + j]) % mod + (f[j][j + k] * t[j + k + 2][i + j]) % mod + (t[j][j + k] * t[j + k + 2][i + j]) % mod) % mod;
t[j][i + j] %= mod;
f[j][i + j] += ((f[j][j + k] * f[j + k + 2][i + j]) % mod) % mod;
f[j][i + j] %= mod;
}
}
}
}
return desired ? t[0][exp.length - 1] : f[0][exp.length - 1];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Main p240 = new Main();
String express = sc.nextLine();
boolean desired = sc.nextBoolean();
long num = p240.num(express, desired);
System.out.println(num);
}
}