1119: 表达式的值

Memory Limit:128 MB Time Limit:1.000 S
Judge Style:Text Compare Creator:
Submit:11 Solved:7

Description

对于1位二进制变量定义两种运算:


运算的优先级是:

1. 先计算括号内的,再计算括号外的。

2. “×”运算优先于“⊕”运算,即计算表达式时,先计算×运算,再计算⊕运算。

例如:计算表达式A⊕B×C时,先计算B×C,其结果再与A做⊕运算。

现给定一个未完成的表达式,例如_+(_*_),请你在横线处填入数字0或者1,请问有多少种填法可以使得表达式的值为0。



Input

每组输入数据的第1行为一个整数L,表示给定的表达式中除去横线外的运算符和括号的个数。
第2行为一个字符串包含L个字符,其中只包含‘(’、‘)’、‘+’、‘*’这4种字符,其中‘(’、‘)’是左右括号,‘+’、‘*’分别表示前面定义的运算符“⊕”和“×”。这行字符按顺序给出了给定表达式中除去变量外的运算符和括号。


数据规模:
对于20%的数据有0≤L≤10;
对于50%的数据有0≤L≤1,000;
对于70%的数据有0≤L≤10,000;
对于100%的数据有0≤L≤100,000;
对于50%的数据输入表达式中不含括号。


Output

每组输出共1行。包含一个整数,即所有的方案数。注意:这个数可能会很大,请输出方案数对10007取模后的结果。


下面是对样例数据的解释:
给定的表达式包括横线字符之后为:_+(_*_)
在横线位置填入(0、0、0)、(0、1、0)、(0、0、1) 时,表达式的值均为0 ,所以共有3种填法。


Sample Input Copy

4
+(*)

Sample Output Copy

3

HINT





#include<cstdio>
#include<stack>
usingnamespacestd;
constintN=100010,mod=10007;
intn;
charstr[N];
stack<int>a,b;
stack<char>c;
inta1,b1,c1,d1;
voidget(){
    a1=a.top(),b1=b.top();
    a.pop();b.pop();
    c1=a.top(),d1=b.top();
    a.pop();b.pop();
}
intmain(){
    //freopen
    scanf("%d",&n);
    scanf("%s",(str+2));
    str[1]='(';str[n+2]=')';
    for(inti=1;i<=n+2;i++){
        if((str[i]=='+'||str[i]=='*')&&str[i-1]!='+'&&str[i-1]!='*'&&str[i-1]!=')'){
            a.push(1);b.push(1);
        }
        if(str[i]=='('){
            c.push(str[i]);
        }
        if(str[i]=='*'){
            if(str[i+1]=='('){
                c.push(str[i]);
                continue;
            }
            while(c.top()=='*'){
                get();
                a.push((a1*c1+a1*d1+b1*c1)%mod);
                b.push((b1*d1)%mod);
                c.pop();
            }
            c.push(str[i]);
        }
        if(str[i]=='+'){
            while(c.top()=='*'){
                get();
                a.push((a1*c1+a1*d1+b1*c1)%mod);
                b.push((b1*d1)%mod);
                c.pop();
            }
            c.push(str[i]);
        }
        if(str[i]==')'){
            while(c.top()!='('){
                if(c.top()=='+'){
                    get();
                    a.push((a1*c1)%mod);
                    b.push((a1*d1+b1*c1+b1*d1)%mod);
                    c.pop();
                }
                if(c.top()=='*'){
                    get();
                    a.push((a1*c1+a1*d1+b1*c1)%mod);
                    b.push((b1*d1)%mod);
                    c.pop();
                }
            }
            c.pop();
        }
        if((str[i]=='+'||str[i]=='*')&&str[i+1]!='('){
            a.push(1);b.push(1);
        }
    }
    printf("%d",a.top()%mod);
     
    return0;
}