You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 1e6 + 10 ;
int e [ N ] , el ; // 表达式数组
int w [ N ] ;
int stk [ N ] , tt ;
/*
可以通过6个测试点, 30分
学到的知识:
1、利用字符串读入后缀表达式
2、利用栈来计算后缀表达式
*/
// 计算表达式的值
int calc ( ) {
// 后缀表达式求值,需要借助栈
tt = 0 ;
// 枚举所有的表达式符号
for ( int i = 1 ; i < = el ; i + + ) {
// 如果是数字,直接入栈
if ( e [ i ] > 0 ) stk [ + + tt ] = w [ e [ i ] ] ; // e[i]=1 --> 1 --> x1---> w[1] <==> w[e[i]]
// 如果是 非 操作符取一个数字出来 运算
else if ( e [ i ] = = - 3 ) { //! 非 运算符
int n1 = stk [ tt - - ] ;
stk [ + + tt ] = ! n1 ; // 对n1取反, 再放回去
} else {
// 如果是与和或的话,那么需要取两个操作符
// 注意一个细节, 这里从栈中取出的数字是反的, n1是后面的, n2是前面的
int n1 = stk [ tt - - ] ;
int n2 = stk [ tt - - ] ;
// 根据e[i]的操作符不同,知道是与还是或
if ( e [ i ] = = - 1 )
stk [ + + tt ] = n2 & n1 ;
else
stk [ + + tt ] = n2 | n1 ;
}
}
return stk [ tt ] ;
}
int main ( ) {
// 文件输入
// freopen("3.in", "r", stdin);
// 读入整行
string s ;
getline ( cin , s ) ; // 带空格的整行数据
// 拆开
for ( int i = 0 ; i < s . size ( ) ; i + + ) {
if ( s [ i ] = = ' ' ) continue ; // 跳过空格
if ( s [ i ] = = ' x ' ) {
i + + ; // 跳过x
int k = 0 ;
while ( i < s . size ( ) & & s [ i ] > = ' 0 ' & & s [ i ] < = ' 9 ' ) k = k * 10 + s [ i + + ] - ' 0 ' ;
e [ + + el ] = k ; // 记录操作符 x1,x2,...,x332
}
// 因为e[]中需要区分是操作符, 变量, 不能直接使用ASCII, 因为比如 ascii(&)=38,可是, 人家k=38,也就是有x38这个变量存在, 你就无法分清楚是&还是x38
// 使用负数-1, -2, -3进行标识, 就不存在这个问题, 肯定能唯一标识是操作符还是操作数
else if ( s [ i ] = = ' & ' )
e [ + + el ] = - 1 ;
else if ( s [ i ] = = ' | ' )
e [ + + el ] = - 2 ;
else if ( s [ i ] = = ' ! ' )
e [ + + el ] = - 3 ;
}
// 打印表达式里面的值,看看有没有什么错误,单元测试
// for (int i = 1; i <= len; i++) cout << e[i] << " ";
// 读入n个变量
// 上面取入的是x1,x2,x3, 也就是变量的下标, 读入的是真正的操作数值
int n ;
cin > > n ;
for ( int i = 1 ; i < = n ; i + + ) cin > > w [ i ] ;
// Q次查询
int Q , x ;
cin > > Q ;
for ( int i = 1 ; i < = Q ; i + + ) {
// 对第x个操作数进行取反
cin > > x ;
// 只时临时修改,不是永久修改
w [ x ] = ! w [ x ] ;
// 重新计算表达式的值
printf ( " %d \n " , calc ( ) ) ;
// 还回来
w [ x ] = ! w [ x ] ;
}
return 0 ;
}