題目傳送門
因爲看不懂題解裏的做法,只好自己寫了一個大模擬+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;
}