列表

详情


NC221781. EvaluateExpression

描述

Moca is learning how to evaluate a mathematical expression, and she is only able to evaluate a complicated expression step by step. But she is very good at counting, so she is curious about how many different orders evaluate a given expression.

In this problem, you only need to consider some simple mathematical expressions consisting of (addition), (multiplication) and . Multiplication has a higher priority than addition. Parentheses can be used to indicate an alternative order. In each step of the evaluation, Moca can choose an operation (addition or multiplication) and replace it with the corresponding result. Notice that Moca can not break the original priority, which may cause her to evaluate an incorrect result. For example, Moca can not choose to evaluate the middle addition in and the middle multiplication in . If many different operations can be evaluated valid, she can choose any one of them.

Moca is very curious. Can you help her count the number of different valid orders to evaluate the given mathematical expression? Since the answer may be very large, you only need to print the answer modulo .

输入描述

The first line contains one integer -- the number of testcases.

For each testcase, there is only one line contains a valid expression consisting of , , and . All the numbers that appear are not greater than  (only one digit). All the that appear are binary operations ( is invalid).

It is guaranteed that the sum of lengths of all expressions does not exceed .

输出描述

For each testcase, print the number of valid evaluation order modulo  in one line.

示例1

输入:

3
1+1+1+1
1*2*3+4*5
1+(2*3*4+5+6)*6+7*8*9

输出:

6
6
784

说明:


In the first example,  has  valid evaluation orders:

1.\underline{1+1}+1+1 \to \underline{2+1}+1 \to \underline{3+1} \to 4
2.\underline{1+1}+1+1 \to 2+\underline{1+1} \to \underline{2+2} \to 4
3.1+\underline{1+1}+1 \to \underline{1+2}+1 \to \underline{3+1} \to 4
4.1+\underline{1+1}+1 \to 1+\underline{2+1} \to \underline{1+3} \to 4
5.1+1+\underline{1+1} \to 1+\underline{1+2} \to \underline{1+3} \to 4
6.1+1+\underline{1+1} \to \underline{1+1}+2 \to \underline{2+2} \to 4

In the second example, 1 \times 2 \times 3+4 \times 5 has valid evaluation orders:

1.\underline{1 \times 2} \times 3+4 \times 5 \to \underline{2 \times 3}+4 \times 5 \to 6+\underline{4 \times 5} \to \underline{6+20} \to 26
2.\underline{1 \times 2} \times 3+4 \times 5 \to 2 \times 3+\underline{4 \times 5} \to \underline{2 \times 3}+20 \to \underline{6+20} \to 26
3.1 \times \underline{2 \times 3}+4 \times 5 \to \underline{1 \times 6}+4 \times 5 \to 6+\underline{4 \times 5} \to \underline{6+20} \to 26
4.1 \times \underline{2 \times 3}+4 \times 5 \to 2 \times 3+\underline{4 \times 5} \to \underline{2 \times 3}+20 \to \underline{6+20} \to 26
5.1 \times 2 \times 3+\underline{4 \times 5} \to \underline{1 \times 2} \times 3+20 \to \underline{2 \times 3}+20 \to \underline{6+20} \to 26
6.1 \times 2 \times 3+\underline{4 \times 5} \to 1 \times \underline{2 \times 3}+20 \to \underline{1 \times 6}+20 \to \underline{6+20} \to 26

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 103ms, 内存消耗: 3032K, 提交时间: 2021-05-09 20:42:20

#include <cstdio>
#include <cassert>
#include <cstring>
#include <vector>
#ifdef XLor
  #include <iostream>
  #define dbg(args...) cout << "\033[32;1m" << #args << " -> ", err(args)
  void err() { std::cout << "\033[39;0m" << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
const int mod = 998244353;
const int maxn = 10000 + 5;

inline int add(int x, int y) {
  x += y;
  return x >= mod ? x -= mod : x;
}
inline int mul(int x, int y) {
  return 1ll * x * y % mod;
}

namespace Comb {
  const int maxc = 100000 + 5;
  int f[maxc], inv[maxc], finv[maxc];
  void init() {
    inv[1] = 1;
    for (int i = 2; i < maxc; i++)
      inv[i] = (mod - mod / i) * 1ll * inv[mod % i] % mod;
    f[0] = finv[0] = 1;
    for (int i = 1; i < maxc; i++) {
      f[i] = f[i - 1] * 1ll * i % mod;
      finv[i] = finv[i - 1] * 1ll * inv[i] % mod;
    }
  }
  int C(int n, int m) {
    if (m < 0 || m > n) return 0;
    return f[n] * 1ll * finv[n - m] % mod * finv[m] % mod;
  }
}
using Comb::C;

int n, siz[maxn * 4];
char s[maxn * 4];

namespace Parser {
  vector<int> edge[maxn * 4];
  int i, tot;

  int factor();
  int term();
  int expr();

  void clear() {
    for (int i = 0; i <= tot; i++) {
      edge[i].clear();
    }
    tot = 0;
    i = 1;
  }

  int factor() {
    if (s[i] == '(') {
      i++;
      int rt = expr();
      assert(s[i] == ')');
      i++;
      return rt;
    } else {
      i++;
      return ++tot;
    }
  }
  int term() {
    int first = factor();
    if (s[i] != '*') {
      return first;
    } else {
      int rt = ++tot;
      edge[rt].push_back(first);
      while (i <= n && s[i] == '*') {
        i++;
        edge[rt].push_back(factor());
      }
      return rt;
    }
  }
  int expr() {
    int first = term();
    if (s[i] != '+') {
      return first;
    } else {
      int rt = ++tot;
      edge[rt].push_back(first);
      while (i <= n && s[i] == '+') {
        i++;
        edge[rt].push_back(term());
      }
      return rt;
    }
  }
}
using Parser::edge;

int f[maxn * 2], g[maxn * 2];
int solve(int u, const vector<int>& a) {
  int sum = 0;
  for (int i = 0; i <= siz[u] + 1; i++) {
    f[i] = g[i] = 0;
  }
  for (int i = 0; i < a.size(); i++) {
    int x = a[i];
    if (i == 0) {
      sum = x;
      f[sum] = 1;
    } else {
      for (int i = 1; i <= sum; i++) {
        f[i] = add(f[i], f[i - 1]);
      }
      g[sum] = f[sum];
      for (int i = sum - 1; i >= 0; i--) {
        g[i] = add(f[i], g[i + 1]);
      }
      for (int i = 0; i <= sum; i++) {
        f[i] = 0;
      }
      if (x == 0) {
        f[0] = g[0];
      } else {
        for (int i = 0; i <= sum; i++) {
          f[i + x] = mul(C(i + x - 1, i), g[i]);
        }
      }
      sum += x + 1;
    }
  }
  int ans = 0;
  for (int i = 0; i <= sum; i++) {
    ans = add(ans, f[i]);
  }
  return ans;
}

int dfs(int u) {
  if (edge[u].empty()) {
    siz[u] = 0;
    return 1;
  }
  siz[u] = (int)edge[u].size() - 1;
  int ans = 1;
  vector<int> vec;
  for (int i = 0; i < edge[u].size(); i++) {
    int v = edge[u][i];
    ans = mul(ans, dfs(v));
    siz[u] += siz[v];
    vec.push_back(siz[v]);
  }
  return mul(ans, solve(u, vec));
}

int main() {
  Comb::init();
  int T; scanf("%d", &T);
  while (T--) {
    scanf("%s", s + 1);
    n = strlen(s + 1);
    Parser::clear();
    printf("%d\n", dfs(Parser::expr()));
  }
  return 0;
}

上一题