Submission #1342562

#TimeUsernameProblemLanguageResultExecution timeMemory
1342562ksujay2Examination 2 (JOI24_examination2)C++20
100 / 100
550 ms419508 KiB
#include <bits/stdc++.h>
using namespace std;

const string SP = "&^|";

struct node {
    int st = 0;
    bool flip = 0;
    node *l, *r;
    void pull() {
        if(st == 1) {
            if(l->st == 0 && r->st == 0) st = 0;
            if(l->st == 2 && r->st == 2) st = 2;
        }
    }
    void push() {
        if(!l) l = new node();
        if(!r) r = new node();
        if(flip) {
            l->apply_flip();
            r->apply_flip();
            flip = 0;
        }
        if(st != 1) {
            l->st = r->st = st;
        }
    }
    void set(int k, int h = 29) {
        if(h == -1) {
            st = 2;
            return;
        }
        push();
        st = 1;
        if((k>>h)&1) {
            r->set(k, h - 1);
        } else {
            r->st = 2;
            l->set(k, h - 1);
        }
        pull();
    }
    bool get(int k, int h = 29) {
        if(h == -1) {
            return st == 2;
        }
        push();
        if((k>>h)&1) {
            return r->get(k, h-1);
        } else {
            return l->get(k, h-1);
        }
    }
    void apply_and(node* o) {
        if(o->st == 0 || st == 0) {
            st = 0;
            return;
        }
        if(o->st == 2) {
            return;
        }
        if(st == 2) {
            *this = *o;
            return;
        }
        push();
        o->push();
        l->apply_and(o->l);
        r->apply_and(o->r);
    }

    void apply_or(node* o) {
        if(o->st == 0) {
            return;
        }
        if(st == 0) {
            *this = *o;
            return;
        }
        if(st == 2 || o->st == 2) {
            st = 2;
            return;
        }
        push();
        o->push();
        l->apply_or(o->l);
        r->apply_or(o->r);
    }

    void apply_flip() {
        st = 2 - st;
        flip ^= 1;
    }

    void apply_xor(node* o) {
        if(o->st == 0) {
            return;
        }
        if(st == 0) {
            *this = *o;
            return;
        }
        if(o->st == 2) {
            apply_flip();
            return;
        }
        if(st == 2) {
            *this = *o;
            apply_flip();
            return;
        }
        push();
        o->push();
        l->apply_xor(o->l);
        r->apply_xor(o->r);
    }

    void print(int lb = 0, int rb = (1 << 30) - 1) {
        if(st == 2) {
            cout << "[" << lb << " " << rb << "]" << " ";
            return;
        }
        if(st == 1) {
            push();
            int m = (lb + rb) / 2;
            l->print(lb, m);
            r->print(m + 1, rb);
        }
    }
    
};

int cnt = 0;

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

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

node* parseNum() {
    assert(match('['));
    int v = 0;
    while(!match(']')) {
        v *= 10;
        v += s[cur] - '0';
        cur++;
    }
    node* n = new node();
    n->set(v);
    return n;
}

node* parse();

node* parsePrimary() {
    if(match('(')) {
        node* n = parse();
        assert(match(')'));
        return n;
    }
    return parseNum();
}

node* parseNot() {
    if(match('!')) {
        node* n = parseNot();
        n->apply_flip();
        return n;
    }
    return parsePrimary();
}

node* parseBinaryOp(int level) {
    if(level == -1) {
        return parseNot();
    }
    node* n = parseBinaryOp(level - 1);
    while(true) {
        if(match(SP[level])) {
            node* o = parseBinaryOp(level - 1);
            if(level == 0) {
                // cout << "AND ";
                // cout << "INPUT\n";
                // n->print();
                // cout << endl;
                // o->print();
                // cout << endl;
                n->apply_and(o);
                // cout << "OUTPUT\n";
                // n->print();
                // cout << endl;
            } else if(level == 1) {
                // cout << "XOR ";
                // cout << "INPUT\n";
                // n->print();
                // cout << endl;
                // o->print();
                // cout << endl;
                n->apply_xor(o);
                // cout << "OUTPUT\n";
                // n->print();
                // cout << endl;
            } else {
                // cout << "OR ";
                // cout << "INPUT\n";
                // n->print();
                // cout << endl;
                // o->print();
                // cout << endl;
                n->apply_or(o);
                // cout << "OUTPUT\n";
                // n->print();
                // cout << endl;
            }
        } else {
            break;
        }
    }
    return n;
}

node* parse() {
    return parseBinaryOp(2);
}

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);
}




int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    cin >> N >> Q;
    cin >> s;
    // parse to form tree
    node* n = parse();
    for(int q = 0; q < Q; q++) {
        int x; cin >> x;
        if(n->get(x)) {
            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...