测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A26404. 逻辑表达式

填空题 困难

题目描述

逻辑表达式

题目描述

给定一个逻辑表达式,以运算符做前缀的形式给出。它包含三种运算符:&、|、^:

& 表示逻辑与运算 | 表示逻辑或运算 ^ 表示逻辑异或运算

表达式还包含三种基本逻辑值:0、1、?。

每个 ? 必须赋值成为 0 或 1 中的一种,请问有多少种不同的赋值方式,可以让整个逻辑表达式的值为 0?

由于答案可能很大,请输出方案数模1,000,000,007 的余数。

前缀表达式的定义如下:

0、1、? 都是前缀表达式;

如果 x,y 都是前缀表达式,则 &xy、|xy、^xy 都是前缀表达式;

不满足以上两条规则的表达式都不是前缀表达式。

输入格式

单个字符串表示输入的前缀表达式

输出格式

单个整数:表示答案模 1,000,000,007 的余数。

输入样例#1

&??

输出样例#1

3

输入样例#2

||??|||?^?|0|1&???|??

输出样例#2

4

输入样例#3

|?^?|0|&??||?^?|1??

输出样例#3

64

说明提示

设 ∣s∣表示输入字符串的长度

50%的数据,1≤∣s∣<1,000

100%的数据,1≤∣s∣<200,000

参考答案

//C语言参考代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MOD 1000000007 typedef struct { long long zero; long long one; } Node; Node stack[200000]; int top = -1; void push(Node node) { stack[++top] = node; } Node pop() { return stack[top--]; } int main() { char s[200001]; scanf("%s", s); int len = strlen(s); for (int i = len - 1; i >= 0; i--) { char c = s[i]; if (c == '0') { push((Node){1, 0}); } else if (c == '1') { push((Node){0, 1}); } else if (c == '?') { push((Node){1, 1}); } else { Node right = pop(); Node left = pop(); Node res = {0, 0}; if (c == '&') { res.zero = (left.zero * right.zero % MOD + left.zero * right.one % MOD + left.one * right.zero % MOD) % MOD; res.one = left.one * right.one % MOD; } else if (c == '|') { res.zero = left.zero * right.zero % MOD; res.one = (left.one * right.zero % MOD + left.zero * right.one % MOD + left.one * right.one % MOD) % MOD; } else if (c == '^') { res.zero = (left.zero * right.zero % MOD + left.one * right.one % MOD) % MOD; res.one = (left.zero * right.one % MOD + left.one * right.zero % MOD) % MOD; } push(res); } } Node result = pop(); printf("%lld\n", result.zero); return 0; }

答案解析

//C++参考代码

#include <iostream>

#include <stack>

#include <vector>

using namespace std;


const int MOD = 1e9+7;


struct Node {

   long long zero, one;

   Node(long long z=0, long long o=0) : zero(z), one(o) {}

};


int main() {

   string s;

   cin >> s;

   stack<Node> st;

   

   for (int i = s.size()-1; i >= 0; --i) {

       char c = s[i];

       if (c == '0') {

           st.push(Node(1, 0));

       } else if (c == '1') {

           st.push(Node(0, 1));

       } else if (c == '?') {

           st.push(Node(1, 1));

       } else {

           Node right = st.top(); st.pop();

           Node left = st.top(); st.pop();

           Node res;

           

if (c == '&') {

               res.zero = (right.zero * left.zero % MOD +

                          right.zero * left.one % MOD +

                          right.one * left.zero % MOD) % MOD;

               res.one = right.one * left.one % MOD;

           } else if (c == '|') {

               res.zero = right.zero * left.zero % MOD;

               res.one = (right.one * left.one % MOD +

                         right.one * left.zero % MOD +

                         right.zero * left.one % MOD) % MOD;

           } else if (c == '^') {

               res.zero = (right.zero * left.zero % MOD +

                          right.one * left.one % MOD) % MOD;

               res.one = (right.zero * left.one % MOD +

                         right.one * left.zero % MOD) % MOD;

           }

           st.push(res);

       }

   }

   

   cout << st.top().zero % MOD << endl;

   return 0;

}

上一题 下一题