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
  | // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct Item { int c; int a; int b; };
struct Query { long long m; int k; int id; };
static inline void add_value_inplace(vector<unsigned long long>& dp, int shiftWords, int shiftBits) {
    int L = (int)dp.size();
    if (shiftBits == 0) {
        for (int i = L - 1; i >= shiftWords; --i) dp[i] |= dp[i - shiftWords];
    } else {
        for (int i = L - 1; i > shiftWords; --i) {
            unsigned long long hi = dp[i - shiftWords] << shiftBits;
            unsigned long long lo = dp[i - shiftWords - 1] >> (64 - shiftBits);
            dp[i] |= (hi | lo);
        }
        if (shiftWords < L) dp[shiftWords] |= (dp[0] << shiftBits);
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n; if(!(cin >> n)) return 0;
    vector<Item> items(n);
    for (int i = 0; i < n; ++i) cin >> items[i].c >> items[i].a >> items[i].b;
    vector<int> idxA(n); iota(idxA.begin(), idxA.end(), 0);
    sort(idxA.begin(), idxA.end(), [&](int i, int j){ return items[i].a < items[j].a; });
    vector<long long> bSorted(n);
    for (int i = 0; i < n; ++i) bSorted[i] = items[i].b;
    sort(bSorted.begin(), bSorted.end());
    int p; cin >> p;
    vector<vector<Query>> groups(n + 1);
    int Kmax = 0;
    vector<long long> Ms(p), Ss(p); vector<int> Ks(p);
    for (int i = 0; i < p; ++i) {
        long long m, s; int k; cin >> m >> k >> s;
        Ms[i] = m; Ss[i] = s; Ks[i] = k; Kmax = max(Kmax, k);
    }
    for (int i = 0; i < p; ++i) {
        long long B = Ms[i] + Ss[i];
        int r = (int)(upper_bound(bSorted.begin(), bSorted.end(), B) - bSorted.begin());
        groups[r].push_back(Query{Ms[i], Ks[i], i});
    }
    int L = (Kmax >> 6) + 1;
    vector<unsigned long long> dp(L);
    vector<char> ans(p, 0);
    for (int r = 0; r <= n; ++r) {
        if (groups[r].empty()) continue;
        sort(groups[r].begin(), groups[r].end(), [](const Query& x, const Query& y){
            if (x.m != y.m) return x.m < y.m; return x.id < y.id;
        });
        long long Bthres = (r > 0 ? bSorted[r - 1] : LLONG_MIN);
        fill(dp.begin(), dp.end(), 0ULL); dp[0] = 1ULL;
        int pos = 0;
        for (const auto& q : groups[r]) {
            while (pos < n && (long long)items[idxA[pos]].a <= q.m) {
                const Item& it = items[idxA[pos]];
                if ((long long)it.b > Bthres) {
                    int c = it.c; int w = c >> 6, b = c & 63;
                    add_value_inplace(dp, w, b);
                }
                ++pos;
            }
            ans[q.id] = (q.k <= Kmax && ((dp[q.k >> 6] >> (q.k & 63)) & 1ULL)) ? 1 : 0;
        }
    }
    for (int i = 0; i < p; ++i) cout << (ans[i] ? "TAK\n" : "NIE\n");
    return 0;
}
  |