记录一个 c k [ 2 ] [ 2 ] ck[2][2] ck[2][2], c k [ 0 / 1 ] [ 0 / 1 ] ck[0/1][0/1] ck[0/1][0/1]表示当前区间左端点选择 a / b , a / b a/b,a/b a/b,a/b能否满足题意,然后区间合并一下。
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;
const ll N=2e5+5;
ll n,m,card[N][2];
struct node{
ll x,y,ck[2][2];
}tree[N<<2];
#define lson (p<<1)
#define rson (p<<1|1)
inline ll read() {
ll x=0;char ch=getchar();bool f=0;
while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
void pushup(ll p) {
rep(i,0,1) rep(j,0,1) {
tree[p].ck[i][j]=0;
rep(k,0,1) rep(l,0,1) {
tree[p].ck[i][j]|=tree[lson].ck[i][k]&tree[rson].ck[l][j]&(card[tree[lson].y][k]<=card[tree[rson].x][l]);
}
}
}
void maketree(ll p,ll x,ll y) {
tree[p].x=x,tree[p].y=y;
if(x==y) {
tree[p].ck[1][1]=tree[p].ck[0][0]=1;return ;
} else {
maketree(lson,x,x+y>>1);
maketree(rson,(x+y>>1)+1,y);pushup(p);
}
}
void update(ll p,ll q) {
if(tree[p].x==tree[p].y) {
tree[p].ck[0][0]=tree[p].ck[1][1]=1;return ;
}
if(q<=tree[lson].y) update(lson,q);
else update(rson,q);pushup(p);
}
int main() {
n=read();
rep(i,1,n) card[i][0]=read(),card[i][1]=read();
maketree(1,1,n);
m=read();
rep(i,1,m) {
ll x=read(),y=read();
swap(card[x][0],card[y][0]);
swap(card[x][1],card[y][1]);update(1,x),update(1,y);
if(tree[1].ck[0][0]|tree[1].ck[0][1]|tree[1].ck[1][0]|tree[1].ck[1][1]) puts("TAK");
else puts("NIE");
}
return 0;
}