CF1175B

简单的模拟。

1. 题意

给定一串语句,并有变量 $x$,初始为 $0$,仅含有一下三种类型:

  1. for n:表示循环 $n$ 次,直到与之匹配的 end
  2. end:表示循环结束。
  3. add:将 $x$ 加一。

执行完后,如果 $x\geq2^{32}$,输出 OVERFLOW!!!,否则输出 $x$ 的值。

2. 思路

$x$ 的值就是 add 的执行次数。

我们可以在记录一个变量 $mul$,表示当前的语句将会被执行多少次。

所以碰到 add 的时候,将当前的 $x$ 加上 $mul$ 即可。

注意,这道题 $mul$ 最大会达到 $100^{5000}$,所以注意我们如果 $mul\geq 2^{32}$,就可以直接赋值为 $2^{32}$。

但是,这里又有一个问题:$mul=2^{32}$ 之后,碰上 end,我们将要 $mul$ 除以当前的循环次数,明显就错误了。

处理方法也很简单:用一个栈记录所有的 for n,然后使用前缀积 $pre$ 维护,于是退栈的时候,我们直接将当前的 $mul$ 赋值为 $pre[top-1]$ 即可。

3. 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;
const int N = 1e5 + 10;
const ll INF = (1ll << 32) - 1;
char str[N];
int n, top;
ll x, stk[N], tmp, pre[N];

void overflow()
{
puts("OVERFLOW!!!");
exit(0);
}

int main()
{
cin >> n;
pre[0] = 1;
while (n --)
{
scanf("%s", str + 1);
if (str[1] == 'a') x += pre[top];
else if (str[1] == 'f')
{
scanf("%lld", &tmp);
stk[++ top] = tmp;
pre[top] = pre[top - 1] * tmp;
if (pre[top]) ;
}
else if (str[1] == 'e') top --;
if (pre[top] > INF) pre[top] = INF + 1;
if (x > INF) overflow();
}
cout << x << endl;
return 0;
}