/* * 成段更新,区间统计颜色的种类(离散化处理线段) */ #include <iostream> #include <cstdio> #include <algorithm> #include <bitset> #include <cstring> #define LL(x) ((x) << 1) #define RR(x) ((x) << 1 | 1) using namespace std; const int N = 10010; struct Line { int l, r; } line[N]; struct Seg_tree { int l, r, coulor; int mid() { return (l + r) >> 1; } } tree[7 * N]; // 6 * N 的时候一直RE,想不明白是什么原因,不是建树满足最大值的3倍就可以了么?? int pos[N * 2]; int len, ans; bitset<N> hash; // 代替bool hash inline void Build(int l, int r, int node) { tree[node].l = l; tree[node].r = r; tree[node].coulor = -1; if (l == r) { return; } int mid = (l + r) >> 1; Build(l, mid, LL(node)); Build(mid + 1, r, RR(node)); } inline void Update(int l, int r, int node, int coulor) { if (l <= tree[node].l && tree[node].r <= r) { tree[node].coulor = coulor; return; } if (tree[node].coulor != -1) { // 父节点不是混合的颜色,把子节点更新为父节点, 并把父节点更新为 -1 tree[LL(node)].coulor = tree[RR(node)].coulor = tree[node].coulor; tree[node].coulor = -1; } int mid = tree[node].mid(); if (r <= mid) Update(l, r, LL(node), coulor); else if (l > mid) Update(l, r, RR(node), coulor); else { Update(l, mid, LL(node), coulor); Update(mid + 1, r, RR(node), coulor); } } inline void Query(int l, int r, int node) { if(l <= tree[node].l && tree[node].r <= r) { if (tree[node].coulor != -1 ){ if(!hash[tree[node].coulor]) { ans++; hash[tree[node].coulor] = true; //return; } } else{ // 其实这里了很多的无效的代码,不过感觉很清楚的 int mid = tree[node].mid(); Query(tree[node].l, mid, LL(node)); Query(mid + 1, tree[node].r, RR(node)); } return ; } int mid = tree[node].mid(); if (r <= mid) Query(l, r, LL(node)); else if (l > mid) Query(l, r, RR(node)); else { Query(l, mid, LL(node)); Query(mid + 1, r, RR(node)); } } inline int Fun(int x) { // 二分不可以在写错了, 查找在离散数组中的下标 int low = 0; int high = len - 1; while (low <= high) { int mid = (low + high) >> 1; //printf("mid :%d/n", mid); if (pos[mid] == x) { return mid; } else if (pos[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return -1; } int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { // 将线段离散化 scanf("%d %d", &line[i].l, &line[i].r); pos[LL(i)] = line[i].l; pos[RR(i)] = line[i].r; } sort(pos, pos + 2 * n); len = 0; for (int i = 0; i < 2 * n; i++) { if (i == 0 || pos[i] != pos[i - 1]) { pos[len++] = pos[i]; } } //printf("%d/n", len); Build(0, len - 1, 1); hash.reset(); for (int i = 0; i < n; i++) { //printf("%d %d /n==", Fun(line[i].l), Fun(line[i].r)); Update(Fun(line[i].l), Fun(line[i].r), 1, i); } ans = 0; //puts("=="); Query(0, len - 1, 1); //puts("====="); printf("%d/n", ans); } }