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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 | #include <bits/stdc++.h>
#define FOR(i, n) for(int i = 0; i < (n); ++i)
#define REP(i, a, b) for(int i = (a); i < (b); ++i)
#define TRAV(i, n) for(auto &i : n)
#define SZ(x) (int)(x).size()
#define PR std::pair
#define MP std::make_pair
#define X first
#define Y second
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::vector<int> VI;
struct Tree{
int BOTTOM;
std::vector<ll> t, u;
std::vector<bool> cl;
void build(int a){
BOTTOM = 1;
while(BOTTOM < a) BOTTOM *= 2;
t.resize(BOTTOM*2);
u.resize(BOTTOM*2);
cl.resize(BOTTOM*2);
}
void upd(int v, int lo, int hi){
if(cl[v]){
t[v] = 0;
if(v < BOTTOM){
u[v<<1] = u[(v<<1)+1] = 0;
cl[v<<1] = cl[(v<<1)+1] = true;
}
cl[v] = false;
}
if(u[v]){
t[v] += u[v]*(hi-lo+1);
if(v < BOTTOM){
u[v<<1] += u[v];
u[(v<<1)+1] += u[v];
}
u[v] = 0;
}
}
void add(int a, int b, int w, int v=1, int lo=0, int hi=-2){
if(hi==-2) hi = BOTTOM-1;
upd(v, lo, hi);
if(a>b) return;
if(a==lo && b== hi){
u[v] += w;
upd(v, lo, hi);
return;
}
int mid = (lo+hi)/2;
add(a, std::min(b, mid), w, v<<1, lo, mid);
add(std::max(a, mid+1), b, w, (v<<1)+1, mid+1, hi);
t[v] = t[v<<1]+t[(v<<1)+1];
}
void clear(int a, int b, int v=1, int lo=0, int hi=-2){
if(hi==-2) hi = BOTTOM-1;
upd(v, lo, hi);
if(a>b) return;
if(a==lo && b== hi){
cl[v] = true;
upd(v, lo, hi);
return;
}
int mid = (lo+hi)/2;
clear(a, std::min(b, mid), v<<1, lo, mid);
clear(std::max(a, mid+1), b, (v<<1)+1, mid+1, hi);
t[v] = t[v<<1]+t[(v<<1)+1];
}
ll query(int a, int b, int v=1, int lo=0, int hi=-2){
if(hi==-2) hi = BOTTOM-1;
upd(v, lo, hi);
if(a>b) return 0;
if(a==lo&&b==hi) return t[v];
int mid = (lo+hi)/2;
return query(a, std::min(b, mid), v<<1, lo, mid)
+ query(std::max(a, mid+1), b, (v<<1)+1, mid+1, hi);
}
};
int main(){
Tree tree;
tree.build(1002137);
int t;
std::scanf("%d", &t);
while(t--){
tree.clear(0, tree.BOTTOM-1);
int n;
std::scanf("%d", &n);
std::set<int> set;
FOR(i, n){
int l, a, b;
std::scanf("%d%d%d", &l, &a, &b);
if(a == b) continue;
if(a > b){
l = -l;
std::swap(a, b);
}
b--;
tree.add(a, b, l);
set.insert(a-1);
// set.insert(a);
// set.insert(a+1);
// set.insert(b-1);
set.insert(b);
// set.insert(b+1);
}
ll have = 0;
int last = 0;
bool good = true;
TRAV(i, set) if(i > 0){
have += tree.query(last+1, i);
if(have < 0){
good = false;
break;
}
last = i;
}
if(have != 0) good = false;
std::printf(good ? "TAK\n" : "NIE\n");
}
return 0;
}
|