Submission #1342490

#TimeUsernameProblemLanguageResultExecution timeMemory
1342490ksujay2Examination 2 (JOI24_examination2)C++20
0 / 100
457 ms16160 KiB
#include <bits/stdc++.h>
using namespace std;

const string SP = "&^|";

enum OP {
    NUM, NOT, AND, XOR, OR
};

const OP bop[] = {AND, XOR, OR};

const int MXN = 1e6;

int cnt = 0;
OP op[MXN];
int v[MXN];
vector<int> ins[MXN];

int N, Q;
string s;
int cur = 0;

int create_node() {
    return cnt++;
}

bool match(char c) {
    if(cur == s.size()) return false;
    if(s[cur] == c) {
        cur++;
        return true;
    }
    return false;
}

int parseNum() {
    assert(match('['));
    int n = create_node();
    while(!match(']')) {
        v[n] *= 10;
        v[n] += s[cur] - '0';
        cur++;
    }
    op[n] = NUM;
    return n;
}

int parse();

int parsePrimary() {
    if(match('(')) {
        int v = parse();
        assert(match(')'));
        return v;
    }
    return parseNum();
}

int parseNot() {
    if(match('!')) {
        int c = parseNot();
        int n = create_node();
        op[n] = NOT;
        ins[n].push_back(c);
        return n;
    }
    return parsePrimary();
}

int parseBinaryOp(int level) {
    if(level == -1) {
        return parseNot();
    }
    int n = parseBinaryOp(level - 1);
    while(true) {
        if(match(SP[level])) {
            int nw = parseBinaryOp(level - 1);
            int p = create_node();
            op[p] = bop[level];
            ins[p].push_back(n);
            ins[p].push_back(nw);
            n = p;
        } else {
            break;
        }
    }
    return n;
}

int parse() {
    return parseBinaryOp(2);
}

const int INF = 1e9;

bool inside(int x, pair<int, int> iv) {
    return iv.first <= x && x <= iv.second;
}

bool inter(pair<int, int> iv1, pair<int, int> iv2) {
    return max(iv1.first, iv2.first) <= min(iv1.second, iv2.second);
}

struct D {
    int flipped = 0;
    set<pair<int, int>> ivs;
    void apply_not() {
        flipped ^= 1;
    }
    void split(int x) {
        auto it = ivs.lower_bound({x + 1, 0});
        if(it == ivs.begin()) return;
        it = prev(it);
        if(inside(x, *it)) {
            pair<int, int> niv1 = {it->first, x - 1};
            pair<int, int> niv2 = {x, it->second};
            if(niv1.first <= niv1.second)
                ivs.insert(niv1);
            if(niv2.first <= niv2.second)
                ivs.insert(niv2);
            ivs.erase(it);
        }
    }
    void or_iv(pair<int, int> iv) {
        split(iv.first);
        split(iv.second + 1);
        if(flipped) {
            while(true) {
                auto it = ivs.lower_bound({iv.second + 1, 0});
                if(it == ivs.begin()) break;
                it = prev(it);
                if(inter(*it, iv)) {
                    ivs.erase(it);
                } else {
                    break;
                }
            }
        } else {
            while(true) {
                auto it = ivs.upper_bound({iv.second + 1, 0});
                if(it == ivs.begin()) break;
                it = prev(it);
                if(inter(*it, iv)) {
                    ivs.erase(it);
                } else {
                    break;
                }
            }
            ivs.insert(iv);
        }
    }
    void or_ivs(D& o) {
        o.apply_flipped();
        for(auto iv : o.ivs) {
            or_iv(iv);
        }
    }
    void apply_flipped() {
        if(flipped) {
            set<pair<int, int>> nivs;
            int l = 0;
            for(auto iv : ivs) {
                if(l <= iv.first - 1)
                    nivs.insert({l, iv.first - 1});
                l = iv.second + 1;
            }
            if(l <= INF) {
                nivs.insert({l, INF});
            }
            ivs = nivs;
            flipped = 0;
        }
    }
};

void dfs(int s, D& d) {
    if(op[s] == NUM) {
        d.ivs.insert({v[s], INF});
    } else if(op[s] == NOT) {
        dfs(ins[s][0], d);
        d.apply_not();
    } else if(op[s] == AND) {
        dfs(ins[s][0], d);
        D d2;
        dfs(ins[s][1], d2);
        if(d.ivs.size() < d2.ivs.size()) swap(d, d2);
        d.apply_not(), d2.apply_not();
        d.or_ivs(d2);
        d.apply_not();
    } else if(op[s] == XOR) {
        dfs(ins[s][0], d);
        D d2;
        dfs(ins[s][1], d2);
        if(d.ivs.size() < d2.ivs.size()) swap(d, d2);
        d.apply_flipped();
        d2.apply_flipped();
        D d3 = d, d4 = d2;
        d.apply_not();
        d.or_ivs(d2);
        d.apply_flipped();
        d.apply_not();

        d4.apply_not();
        d4.apply_flipped();
        d3.or_ivs(d4);
        d3.apply_not();

        d.apply_flipped();
        d3.apply_flipped();

        d.or_ivs(d3);
    } else {
        dfs(ins[s][0], d);
        D d2;
        dfs(ins[s][1], d2);
        if(d.ivs.size() < d2.ivs.size()) swap(d, d2);
        d.or_ivs(d2);
    }
    d.apply_flipped();
}


int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    cin >> N >> Q;
    cin >> s;
    // parse to form tree
    int rt = parse();
    D ivs;
    dfs(rt, ivs);
    ivs.apply_flipped();
    for(int q = 0; q < Q; q++) {
        int x; cin >> x;
        auto it = ivs.ivs.upper_bound({x, INF});
        if(it == ivs.ivs.begin()) {
            cout << "False\n";
            continue;
        }
        it = prev(it);
        if(inside(x, *it)) cout << "True\n";
        else cout << "False\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...