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
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct Node {
long long total;
long long bestPrefix;
long long bestSuffix;
long long bestSubarray;
Node(long long v = 0) : total(v), bestPrefix(v), bestSuffix(v), bestSubarray(v) {}
};
Node mergeNode(const Node& L, const Node& R) {
Node res;
res.total = L.total + R.total;
res.bestPrefix = max(L.bestPrefix, L.total + R.bestPrefix);
res.bestSuffix = max(R.bestSuffix, R.total + L.bestSuffix);
res.bestSubarray = max({L.bestSubarray, R.bestSubarray, L.bestSuffix + R.bestPrefix});
return res;
}
struct SegTree {
int n;
vector<Node> tree;
vector<long long> val;
SegTree(int n_, long long base) : n(n_), tree(4*n_), val(n_+1, base) {
build(1, 1, n);
}
void build(int idx, int l, int r) {
if (l == r) { tree[idx] = Node(val[l]); return; }
int mid = (l + r) >> 1;
build(idx<<1, l, mid);
build(idx<<1|1, mid+1, r);
tree[idx] = mergeNode(tree[idx<<1], tree[idx<<1|1]);
}
void update(int pos, long long delta) { update(1, 1, n, pos, delta); }
void update(int idx, int l, int r, int pos, long long delta) {
if (l == r) {
val[pos] += delta;
tree[idx] = Node(val[pos]);
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) update(idx<<1, l, mid, pos, delta);
else update(idx<<1|1, mid+1, r, pos, delta);
tree[idx] = mergeNode(tree[idx<<1], tree[idx<<1|1]);
}
long long maxSubarray() const { return tree[1].bestSubarray; }
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
long long k, d;
if (!(cin >> n >> m >> k >> d)) return 0;
// q[i] = p[i] - k. 시작값은 -k
SegTree st(n, -k);
for (int i = 0; i < m; ++i) {
int r; long long x;
cin >> r >> x;
st.update(r, x);
cout << (st.maxSubarray() > k * d ? "NIE" : "TAK") << '\n';
}
return 0;
}
|