二维离散化+区间线段树
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) ((x)<<1)
#define r(x) ((x)<<1|1)
#define lowbit(x) ((x)&(-(x)))
#define abs(x) ((x)>=0?(x):(-(x)))
#define ms(a,b) memset(a,b,sizeof(a))
#define NSYNC std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
using namespace std;
const int MAXN = 222222;
struct Node {
int l, r;//区间[l,r]
int add;//区间的延时标记
//int sum;//区间和
//int mx; //区间最大值
int mn; //区间最小值
}tree[MAXN << 2];//一定要开到4倍多的空间
void pushup(int index) {
//tree[index].sum = tree[index << 1].sum + tree[index << 1 | 1].sum;
//tree[index].mx = max(tree[index << 1].mx, tree[index << 1 | 1].mx);
tree[index].mn = min(tree[index << 1].mn, tree[index << 1 | 1].mn);
}
void pushdown(int index) {
//说明该区间之前更新过
//要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新
if (tree[index].add) {
//替换原来的值
//tree[index<<1].sum = (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
//tree[index<<1|1].sum = (tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
//tree[index<<1].mx = tree[index].add;
//tree[index<<1|1].mx = tree[index].add;
tree[index << 1].mn = tree[index].add;
tree[index << 1 | 1].mn = tree[index].add;
tree[index << 1].add = tree[index].add;
tree[index << 1 | 1].add = tree[index].add;
tree[index].add = 0;
//在原来的值的基础上加上val
/*tree[index << 1].sum += (tree[index << 1].r - tree[index << 1].l + 1)*tree[index].add;
tree[index << 1 | 1].sum += (tree[index << 1 | 1].r - tree[index << 1 | 1].l + 1)*tree[index].add;
tree[index << 1].mx += tree[index].add;
tree[index << 1 | 1].mx += tree[index].add;
tree[index << 1].mn += tree[index].add;
tree[index << 1 | 1].mn += tree[index].add;
tree[index << 1].add += tree[index].add;
tree[index << 1 | 1].add += tree[index].add;
tree[index].add = 0;*/
}
}
void build(int l, int r, int index) {
tree[index].l = l;
tree[index].r = r;
tree[index].add = 0;//刚开始一定要清0
if (l == r) {
//scanf("%d", &tree[index].sum);
tree[index].mn;// = tree[index].mx = tree[index].sum;
return;
}
int mid = (l + r) >> 1;
build(l, mid, index << 1);
build(mid + 1, r, index << 1 | 1);
pushup(index);
}
void update(int l, int r, int index, int val) {
if (l <= tree[index].l && r >= tree[index].r) {
//tree[index].sum = (tree[index].r-tree[index].l+1)*val;
tree[index].mn = val;
//tree[index].mx = val;
tree[index].add = val;//延时标记
//tree[index].sum += (tree[index].r - tree[index].l + 1)*val;
//tree[index].mn += val;
//tree[index].mx += val;
//tree[index].add += val;//延时标记
return;
}
pushdown(index);
int mid = (tree[index].l + tree[index].r) >> 1;
if (l <= mid) {
update(l, r, index << 1, val);
}
if (r > mid) {
update(l, r, index << 1 | 1, val);
}
pushup(index);
}
int query(int l, int r, int index) {
if (l <= tree[index].l && r >= tree[index].r) {
//return tree[index].sum;
//return tree[index].mx;
return tree[index].mn;
}
pushdown(index);
int mid = (tree[index].l + tree[index].r) >> 1;
//int ans = 0;
//int Max = 0;
int Min = INF;
if (l <= mid) {
//ans += query(l, r, index << 1);
//Max = max(query(l, r, index << 1), Max);
Min = min(query(l, r, index << 1), Min);
}
if (r > mid) {
//ans += query(l, r, index << 1 | 1);
//Max = max(query(l, r, index << 1 | 1), Max);
Min = min(query(l, r, index << 1 | 1), Min);
}
//return ans;
//return Max;
return Min;
}
struct node {
int s, val;
} demo[222222];
bool cmp(const node &a,const node &b) {
return a.s < b.s;
}
bool cmp1(const node &a, const node &b) {
return a.val < b.val;
}
int lId[222222], rId[222222], id[222222 << 2];
void slove() {
int n;
scanf("%d", &n);
int cnt = 0;
for (int i = 1; i <= n*2; i+=2) {
scanf("%d%d", &demo[i].s, &demo[i+1].s);
demo[i].val = i;
demo[i + 1].val = i + 1;
}
sort(demo + 1, demo + n * 2 + 1, cmp);
int now = 1, temp = demo[1].s;
demo[1].s = 1;
for (int i = 2; i <= n * 2; i++) {
if (demo[i].s - temp > 1) now += 2;
else if (demo[i].s - temp == 1)now++;
temp = demo[i].s;
demo[i].s = now;
}
sort(demo + 1, demo + n * 2 + 1, cmp1);
build(1, 211111, 1);
for (int i = 1; i <= n * 2; i += 2) {
update(demo[i].s, demo[i+1].s, 1, demo[i].val);
}
int ans = 0;
for (int i = 1; i <= n * 2; i += 2) {
//cout << demo[i].s << " " << demo[i + 1].s << " " << demo[i].val <<" "<< query(demo[i].s, demo[i + 1].s, 1) << endl;
if (query(demo[i].s, demo[i + 1].s, 1) == demo[i].val)
ans++;
}
printf("%d\n", ans);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
slove();
}
return 0;
}