# POJ 2528 Mayor's posters 离散化和线段树题解

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int SIZE = 10005;
bool hashColor[SIZE];
int le[SIZE], ri[SIZE];
int discreteArr[SIZE<<2];//因为这里也许需要四倍的SIZE内存
int seg[SIZE<<4];
int visiblePosts;

inline int lChild(int rt) { return rt<<1; }
inline int rChild(int rt) { return rt<<1|1; }

inline void pushDown(int rt)
{
if (seg[rt])
{
seg[lChild(rt)] = seg[rChild(rt)] = seg[rt];
seg[rt] = 0;
}
}

void build(int l, int r, int rt)
{
seg[rt] = 0;
if (l == r) return ;
int m = l + ((r-l)>>1);
build(l, m, lChild(rt));
build(m+1, r, rChild(rt));
}

void update(int ql, int qr, int col, int l, int r, int rt)
{
if (ql <= l && r <= qr)
{
seg[rt] = col;
return;
}
pushDown(rt);
int m = l + ((r-l)>>1);
if (ql <= m) update(ql, qr, col, l, m, lChild(rt));
if (m < qr) update(ql, qr, col, m+1, r, rChild(rt));
}

void query(int l, int r, int rt)
{
if (seg[rt])
{
if (!hashColor[seg[rt]])
{
visiblePosts++;
hashColor[seg[rt]] = true;
}
return ;
}
if (l == r) return ;//注意这里没有poster的时候
int m = l + ((r-l)>>1);
query(l, m, lChild(rt));
query(m+1, r, rChild(rt));
}

int biSearch(int arr[], int key, int n)
{
int l = 1, r = n-1, m = -1;
while (l <= r)
{
m = l + ((r-l)>>1);
if (arr[m] < key) l = m+1;
else if (key < arr[m]) r = m-1;
else break;
}
return m;
}

int main()
{
int T, n;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
int disN = 1;
for (int i = 1; i <= n; i++)
{
scanf("%d %d", &le[i], &ri[i]);
discreteArr[disN++] = le[i];
discreteArr[disN++] = ri[i];
}
sort(discreteArr+1, discreteArr+disN);

int j = 2;
for (int i = 2; i < disN; i++)
{
if (discreteArr[i] != discreteArr[i-1])
discreteArr[j++] = discreteArr[i];
}
for (int i = j-1; i > 1; i--)
{
if (discreteArr[i] != discreteArr[i-1] + 1)
discreteArr[j++] = discreteArr[i-1] + 1;
}
sort(discreteArr + 1, discreteArr + j);
build(1, j-1, 1);
for (int i = 1; i <= n; i++)
{
int ql = biSearch(discreteArr, le[i], j);
int qr = biSearch(discreteArr, ri[i], j);
update(ql, qr, i, 1, j-1, 1);
}
visiblePosts = 0;
memset(hashColor, 0, sizeof(bool) * (n+1));
query(1, j-1, 1);
printf("%d\n", visiblePosts);
}
return 0;
}