题目链接:https://www.luogu.com.cn/problem/P1310
首先因为有优先级和括号,可以先把表达式化成后缀表达式的形式,其中用'.'表示这一个点是数字。
用u记录得到0的方案数,v记录得到1的方案数。
设两个步骤的运算结果经过每个符号到一个结果时,
第一个运算结果算出0的方案数为t1,1的方案数为t2。第二个算出0的方案数为t3,算出1的方案数为t4。
则有: 当符号是“⊕”时,得到0的方案数为t1*t3,1的方案数:t1*t4+t2*t3+t2*t4
当符号是“×”时,得到0的方案数为t1*t3+t1*t4+t2*t3,1的方案数:t2*t4
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 const int N=100005; 5 const int mod=10007; 6 int l,top,k; 7 char c[N],ans[N],st[N]; 8 int u[N],v[N]; 9 int main(){ 10 scanf("%d",&l); 11 scanf("%s",c); 12 ans[++k]='.'; 13 for(int i=0;i<l;i++){ 14 if(c[i]=='('||c[i]=='*') st[++top]=c[i]; 15 if(c[i]=='+'){ 16 while(st[top]=='*') ans[++k]=st[top--]; 17 st[++top]=c[i]; 18 } 19 if(c[i]==')'){ 20 while(st[top]!='(') ans[++k]=st[top--]; 21 top--; 22 } 23 if(c[i]!='('&&c[i]!=')') ans[++k]='.'; 24 } 25 while(top) ans[++k]=st[top--]; 26 for(int i=1;i<=k;i++){ 27 if(ans[i]=='.'){ 28 u[++top]=1; 29 v[top]=1; 30 } 31 if(ans[i]=='*'){ 32 top--; 33 u[top]=(u[top+1]*u[top]+v[top]*u[top+1]+u[top]*v[top+1])%mod; 34 v[top]=(v[top+1]*v[top])%mod; 35 } 36 if(ans[i]=='+'){ 37 top--; 38 v[top]=(v[top+1]*v[top]+u[top]*v[top+1]+v[top]*u[top+1])%mod; 39 u[top]=(u[top+1]*u[top])%mod; 40 } 41 } 42 printf("%d",u[1]); 43 return 0; 44 }