P7073
[CSP-J2020] 表达式
考场上写挂了,最后只有35pts。
所以快
先给每一个元素标号,再通过栈来建一颗后缀表达式的树。
假如一个点的改变对整棵树有影响就不标记,并继续搜索其子树,否则就将其以及其子树全部标记。
然后问题是我的取反只能取一次。
真的脑子不够用了,居然查了有半个小时。。
2.14KB的代码我也真是神仙。。。
时间复杂度
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const ll N=1e5,M=1e6;
ll m,n,cnt,tmp,tot,top,rt,ans,q,x;
string s;
ll a[N+5],b[M+5],st[M+5],rf[N+5],fa[M+5],l[M+5],r[M+5],fei[M+5],c[M+5],f[M+5];
ll dfs(ll p) {
if(b[p]==-1) return f[p]=fei[p]?!(dfs(l[p])&dfs(r[p])):dfs(l[p])&dfs(r[p]);
if(b[p]==-2) return f[p]=fei[p]?!(dfs(l[p])|dfs(r[p])):dfs(l[p])|dfs(r[p]);
if(b[p]>0) return f[p]=fei[p]?!a[b[p]]:a[b[p]];
return f[p];
}
void fg(ll p,ll flg) {
if(flg==1) {
c[p]=1;
if(b[p]<0) {
fg(l[p],1);fg(r[p],1);
}
return;
}
if(b[p]<0) {
if(b[p]==-1) {
if(f[l[p]]==0) fg(r[p],1);
if(f[r[p]]==0) fg(l[p],1);
if(f[l[p]]==1) fg(r[p],0);
if(f[r[p]]==1) fg(l[p],0);
}
if(b[p]==-2) {
if(f[l[p]]==1) fg(r[p],1);
if(f[r[p]]==1) fg(l[p],1);
if(f[l[p]]==0) fg(r[p],0);
if(f[r[p]]==0) fg(l[p],0);
}
}
return;
}
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
return ret*f;
}
void write(ll x) {
if(x<0) {x=-x;putchar('-');}
if(x>10) write(x/10);
putchar(x%10+48);
}
int main() {
getline(cin,s);
m=s.size();
n=read();
for(ll i=1;i<=n;i++) {
a[i]=read();
}
while(cnt<m) {
if(s[cnt]=='x') {
cnt++;tmp=0;
while(s[cnt]!=' '&&cnt<m) {
tmp=tmp*10+s[cnt]-48;cnt++;
}
b[++tot]=tmp;rf[tmp]=tot;
}
else {
if(s[cnt]=='&') b[++tot]=-1;
if(s[cnt]=='|') b[++tot]=-2;
if(s[cnt]=='!') b[++tot]=-3;
}
cnt++;
}
for(ll i=1;i<=tot;i++) {
if(b[i]>0) {
st[++top]=i;
}
else {
if(b[i]==-1||b[i]==-2) {
l[i]=st[top];r[i]=st[top-1];
fa[st[top]]=i;fa[st[top-1]]=i;
top--;st[top]=i;
}
if(b[i]==-3) {
fei[st[top]]=!fei[st[top]];
}
}
}
for(ll i=1;i<=tot;i++) {
if(b[i]!=-3&&fa[i]==0) {
rt=i;break;
}
}
memset(f,-1,sizeof(f));
ans=dfs(rt);
fg(rt,0);
q=read();
for(ll i=1;i<=q;i++) {
x=read();
write(c[rf[x]]?ans:!ans);putchar('\n');
}
return 0;
}