1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <cstdint>
#include <tuple>
#include <unordered_map>
#include <variant>
#include <stack>

namespace {
    using operacja_t = std::tuple<uint32_t, uint32_t, uint32_t>;
    using operacje_t = std::unordered_map<uint32_t, operacja_t>;
    using operacje_wyniki_t = std::variant<bool, operacja_t>;
    using obliczone_t = std::unordered_map<uint32_t, bool>;

    using std::cin, std::cout;
    using std::stack;
    using std::holds_alternative, std::get;
    using std::unordered_map;

    uint32_t n, m, q;
    operacje_t mapa;
    stack<operacje_wyniki_t> s;

    bool wykonaj_operacje(uint32_t o, bool a, bool b) {
        if (o == 1) return a || b;
        if (o == 2) return a && b;
        return !a;
    }

    bool czyZawiera(uint32_t x, uint32_t v, unordered_map<uint32_t, obliczone_t> & obliczone) {
        if (x <= n)
            return v % x == 0;

        stack<operacje_wyniki_t>().swap(s);
        s.push(mapa[x]);
        while (!(s.size() == 1 && holds_alternative<bool>(s.top()))) {
            if (holds_alternative<operacja_t>(s.top())) {
                x = get<1>(get<operacja_t>(s.top()));
                if (x <= n) s.push(v % x == 0);
                else if (obliczone[v - n - 1].contains(x)) s.push(obliczone[v - n - 1][x]);
                else s.push(mapa[x]);
            } else { 
                bool a = get<bool>(s.top());
                s.pop();
                if (holds_alternative<bool>(s.top())) {
                    bool b = get<bool>(s.top());
                    s.pop();
                    bool c = wykonaj_operacje(get<0>(get<operacja_t>(s.top())), b, a);
                    obliczone[v - n - 1][get<2>(get<operacja_t>(s.top()))] = a;
                    s.pop();
                    s.push(c);
                } else {
                    obliczone[v - n - 1][get<1>(get<operacja_t>(s.top()))] = a;
                    if (get<0>(get<operacja_t>(s.top())) == 3) {
                        s.pop();
                        s.push(!a);
                    } else {
                        x = get<2>(get<operacja_t>(s.top()));
                        s.push(a);
                        if (x <= n) s.push(v % x == 0);
                        else if (obliczone[v - n - 1].contains(x)) s.push(obliczone[v - n - 1][x]);
                        else s.push(mapa[x]);
                    }
                }
            }
        }
        return get<bool>(s.top());
    }
}

int main() {
    uint32_t o, x, y, v;
    cin >> n >> m >> q;
    unordered_map<uint32_t, obliczone_t> obliczone;
    for (uint32_t i = 1; i <= m; ++i) {
        cin >> o >> x;
        if (o < 3) cin >> y;
        else y = 0;
        mapa.insert({n + i, {o, x, y}});
    }
    for (uint32_t j = 1; j <= q; ++j) {
        cin >> x >> v;
        if (czyZawiera(x, v, obliczone)) cout << "TAK\n";
        else cout << "NIE\n";
    }
}