55 pts 警示后人
查看原帖
55 pts 警示后人
414231
_Fatalis_楼主2023/9/12 21:25

注意 C++ 短路机制。


                // return tv[u] = (init(nd[u].lc) && init(nd[u].rc));
                // 右边的 init 有可能被短路
                ll = init(nd[u].lc), rr = init(nd[u].rc);
                return tv[u] = (ll && rr);
// Copyright 2023 Lotuses
#include <cstdio>
#include <cctype>
#include <cstring>
#include <stack>
#include <vector>

template<typename T>
void read(T &r) { r = 0; static char ch, last; ch = getchar(), last = 'z'; while (ch < '0' || ch > '9') last = ch, ch = getchar(); while (ch >= '0' && ch <= '9') r = (r << 1) + (r << 3) + (ch ^ 48), ch = getchar(); r = (last == '-') ? -r : r; }
template<typename T, typename...Ts>
void read(T &arg, Ts&...arg_left) { read(arg); read(arg_left...); }

template<typename T>
void write(T x) { if (x < 0) putchar('-'), x = -x; int len = 0; static char ch[100]; while (x) ch[++len] = x % 10 + '0', x /= 10; if (!len) ch[++len] = '0'; while (len) putchar(ch[len--]); }
template<typename T, typename...Ts>
void write(T arg, Ts...arg_left) { write(arg); putchar(' '); write(arg_left...); }
template<typename T>
void writeln(T x) { write(x); putchar('\n'); }
template<typename T, typename...Ts>
void writeln(T arg, Ts...arg_left) { write(arg); putchar(' '); write(arg_left...); putchar('\n'); }

// #define __DEBUG
#ifdef __DEBUG
#define debug(arg, args...) { printf("db <%d> ", __LINE__); writeln(arg, ##args); }
#else
#define debug(arg, args...) {}
#endif

const int maxn = 2e6 + 10;
char ch[maxn];
int mp[255];
std::vector<int> v;

int input() {
    mp['!'] = -1; mp['&'] = -2; mp['|'] = -3;
    int r;
    while (true) {
        scanf("%s", ch);
        if (isdigit(ch[0])) {
            sscanf(ch, "%d", &r);
            return r;
        } else {
            if (ch[0] == 'x') {
                sscanf(ch + 1, "%d", &r);
                v.push_back(r);
            } else {
                v.push_back(mp[ch[0]]);
            }
        }
    }
}

struct Node {
    int lc, rc, fa, x;
} nd[maxn];
int len = 0;
int ins(int lc, int rc, int x) {
    int id = ++len;
    nd[id] = {lc, rc, -1, x};
    return id;
}
std::stack<int> st;
int rt;

void bt() {
    int l, r, fa;
    for (int x : v) {
        if (x > 0) {
            st.push(ins(-1, -1, x));
        } else if (x == -1) {
            l = st.top(); st.pop();
            fa = ins(l, -1, x);
            nd[l].fa = fa;
            st.push(fa);
        } else {
            l = st.top(); st.pop();
            r = st.top(); st.pop();
            fa = ins(l, r, x);
            nd[l].fa = nd[r].fa = fa;
            st.push(fa);
        }
    }
    rt = 1;
    while (~nd[rt].fa) {
        rt = nd[rt].fa;
    }
}

bool xv[maxn], tv[maxn];
bool init(int u) {
    if (nd[u].x > 0) {
        return tv[u] = xv[nd[u].x];
    } else {
        bool ll, rr;
        switch (nd[u].x) {
            case -1:
                return tv[u] = (!init(nd[u].lc));
            case -2:
                // return tv[u] = (init(nd[u].lc) && init(nd[u].rc));
                ll = init(nd[u].lc), rr = init(nd[u].rc);
                return tv[u] = (ll && rr);
            case -3:
                // return tv[u] = (init(nd[u].lc) && init(nd[u].rc));
                ll = init(nd[u].lc), rr = init(nd[u].rc);
                return tv[u] = (ll || rr);
        }
    }
}

// (-1 = !)  (-2 = &)  (-3 = |)
int chk[maxn];
void init2(int u) {
    if (nd[u].x > 0) {
        chk[nd[u].x] = true;
    } else {
        if (nd[u].x == -1) {
            init2(nd[u].lc);
        } else if (nd[u].x == -2) {
            if (tv[nd[u].lc]) init2(nd[u].rc);
            if (tv[nd[u].rc]) init2(nd[u].lc);
        } else if (nd[u].x == -3) {
            if (!tv[nd[u].lc]) init2(nd[u].rc);
            if (!tv[nd[u].rc]) init2(nd[u].lc);
        }
    }
}

int main() {
    #ifdef LOCAL
        freopen(".in", "r", stdin);
        freopen(".out", "w", stdout);
    #endif
    
    int n = input();
    bt();
    for (int i = 1; i <= n; i++) {
        read(xv[i]);
    }
    init(rt);
    init2(rt);
    int T;
    read(T);
    while (T--) {
        int c;
        read(c);
        writeln(tv[rt] ^ chk[c]);
    }
    return 0;
}

2023/9/12 21:25
加载中...