题目传送门
因为看不懂题解里的做法,只好自己写了一个大模拟+DP.对于带括号的式子,从里到外一层一层的处理括号,将其转化为一个数(即括号内可获得的方案数),这样做可以保证我们每次处理的都是一个不带括号的式子,只需考虑算式优先级即可,先算(*),然后将(*)的结果转化成数字,重新构成一个只含+的式子.
思维上比较简单,难度主要在于代码,需要考虑怎样一层层向里和向外处理括号的许多细节,还需要考虑最外面一层状态转移的多种情况,和处理完(*)后,转化只含+的式子的多种情况.
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#define mod 10007
using namespace std;
int n,num = 1,p,sum,pp,ans[200001][2],fh[200001],_num = 1;
int f_ans[200001][2];
bool vis[200001],flag;
string l,l1;
struct kkk {
int _1,_0;
};
inline kkk maxin(int deep,bool len) {
int tot = 0,oo = 0,_tot = 0;;
bool maxx = 0;
map<int ,map<int ,int> > f,f_f;
map<int ,bool> mx,fl;
for(p;p < sum; p++) {
if(deep != 1) {
maxx = 0;
if(l[p] == ')') break;;
if(l[p] == '_' && l[p-1] == '+') {
f[++tot][1] = 1;
f[tot][0] = 1;
maxx = 1;
}
if(l[p-1] == '*' && l[p] == '_') {
f[++tot][1] = 1;
f[tot][0] = 1;
maxx = 1;
}
if(l[p-1] == '*') mx[++_tot] = 1;
if(l[p-1] == '+') mx[++_tot] = 0;
if(l[p] == '(') {
p++;
kkk u = maxin(deep + 1,1);
f[++tot][1] = u._1;
f[tot][0] = u._0;
continue;
}
if(l[p-1] == '(' && l[p] == '_') {
f[++tot][1] = 1;
f[tot][0] = 1;
}
}
else {
maxx = 0;
if(l[p] == ')') break;
if(l[p-1] == '+' && l[p] == '_') {
ans[++num][1] = 1;
ans[num][0] = 1;
maxx = 1;
}
if(l[p-1] == '*' && l[p] == '_') {
ans[++num][1] = 1;
ans[num][0] = 1;
maxx = 1;
}
if(l[p-1] == '*') fh[++_num] = 1;
if(l[p-1] == '+') fh[++_num] = 0;
if(l[p] == '_' && p == 0) {
ans[num][1] = 1;
ans[num][0] = 1;
flag = 1;
}
if(l[p] == '(') {
p++;
kkk u;
u = maxin(deep + 1,1);
ans[++num][1] = u._1;
ans[num][0] = u._0;
continue;
}
}
}
if(deep != 1) {
for(int i = 1;i <= _tot; i++)
if(mx[i] == 1) {
f[i+1][0] = f[i][1] % mod * f[i+1][0] % mod + f[i][0] % mod * f[i+1][0] % mod + f[i+1][1] % mod * f[i][0] % mod;
f[i+1][1] = f[i][1] % mod * f[i+1][1] % mod;
fl[i] = 1;
}
for(int i = 1;i <= tot; i++)
if(!fl[i])
f_f[++oo][0] = f[i][0] % mod,f_f[oo][1] = f[i][1] % mod;
for(int i = 2;i <= oo; i++) {
f_f[i][1] = f_f[i][0] % mod * f_f[i-1][1] % mod + f_f[i][1] % mod * f_f[i-1][0] % mod + f_f[i][1] % mod * f_f[i-1][1] % mod;
f_f[i][0] = f_f[i-1][0] % mod * f_f[i][0] % mod;
}
}
kkk o;
o._0 = f_f[oo][0] % mod;
o._1 = f_f[oo][1] % mod;
return o;
}
int main() {
scanf("%d",&n);
cin >> l1;
for(int i = 0;i < n; i++) {
if(l1[i] == '(') {
l = l + l1[i];
continue;
}
if(l1[i] == '+' || l1[i] == '*') {
if(i == 0 || l1[i-1] != ')') {
l = l + '_' + l1[i];
continue;
}
l = l + l1[i];
}
if(l1[i] == ')' && l1[i-1] != ')') {
l = l + '_' + l1[i];
continue;
}
if(l1[i] == ')')
l = l + ')';
}
sum = l.length();
if(l[sum-1] != ')') l = l + '_';
sum = l.length();
maxin(1,0);
bool lm = 0;
for(int i = 2;i <= _num; i++) {
if(fh[i] == 1 && !flag) {
ans[i+1][0] = ans[i][1] % mod * ans[i+1][0] % mod + ans[i][0] % mod * ans[i+1][0] % mod + ans[i+1][1] % mod * ans[i][0] % mod;
ans[i+1][1] = ans[i][1] % mod * ans[i+1][1] % mod;
vis[i] = 1;
}
if(fh[i] == 1 && flag) {
ans[i][0] = ans[i-1][1] % mod * ans[i][0] % mod + ans[i-1][0] % mod * ans[i][0] % mod + ans[i][1] % mod * ans[i-1][0] % mod;
ans[i][1] = ans[i-1][1] % mod * ans[i][1] % mod;
vis[i-1] = 1;
lm = 1;
}
}
sum = 0;
for(int i = 2;i <= num; i++)
if(!vis[i])
f_ans[++sum][0] = ans[i][0] % mod,f_ans[sum][1] = ans[i][1] % mod;
for(int i = 2;i <= sum; i++) {
f_ans[i][1] = f_ans[i][0] % mod * f_ans[i-1][1] % mod + f_ans[i][1] % mod * f_ans[i-1][0] % mod + f_ans[i][1] % mod * f_ans[i-1][1] % mod;
f_ans[i][0] = f_ans[i-1][0] % mod * f_ans[i][0] % mod;
}
printf("%d ",f_ans[sum][0] % mod);
return 0;
}