#include <iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
const int M = 2*1e4 + 10;
const int N = 1e6;
int f[M][2];
int co[M];
typedef struct
{
int cover;
int left, right;
}P;
P p[4*M];
typedef struct
{
int num;
int p;
}Q;
Q q[2 * M];
bool cmp(const Q&a, const Q&b)
{
return a.num<b.num;
}
void build(int L, int R, int k)
{
p[k].left = L;
p[k].right = R;
p[k].cover = 0;
if (L == R)
return;
int mid = (L + R) >> 1;
build(L, mid, k << 1);
build(mid + 1, R, k << 1 | 1);
}
void update(int L, int R, int id, int d)
{
if (p[id].left == L&&p[id].right == R)
{
p[id].cover = d;
return;
}
if (p[id].cover>0)
{
p[id << 1].cover = p[id].cover;
p[id << 1 | 1].cover = p[id].cover;
p[id].cover = 0;
}
int mid = (p[id].left + p[id].right) >> 1;
if (R <= mid)
update(L, R, id << 1, d);
if (L>mid)
update(L, R, id << 1 | 1, d);
if (L <= mid&&R>mid)
{
update(L, mid, id << 1, d);
update(mid + 1, R, id << 1 | 1, d);
}
}
void query(int d)
{
if (p[d].cover>0)
{
co[p[d].cover] = 1;
p[d].cover=0;
return;
}
if (p[d].left == p[d].right)
return;
query( d << 1 );
query( d << 1 | 1 );
}
int main()
{
int T, n;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
memset(f,0,sizeof(f));
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &f[i][0], &f[i][1]);
q[2 * i - 1].num = f[i][0];
q[2 * i - 1].p = i;
q[2 * i].num = f[i][1];
q[2 * i].p = -1 * i;
}
sort(q + 1, q +1+ 2 * n, cmp);
int temp = q[1].num, t = 1;
for (int i = 1; i <= 2 * n; i++)
{
if (temp != q[i].num)
{
t++;
temp = q[i].num;
}
if (q[i].p>0)
f[q[i].p][0] = t;
else
f[q[i].p*-1][1] = t;
}
//for(int i=1;i<=n;i++)
//cout<<f[i][0]<<" "<<f[i][1]<<endl;cout<<"t= "<<t<<endl;
build(1, t, 1);
for (int i = 1; i <= n; i++)
update(f[i][0], f[i][1], 1, i);
memset(co, 0, sizeof(co));
int ans = 0;
query(1);
for (int i = 1; i <= t; i++)
if (co[i] == 1)
ans++;
printf("%d\n", ans);
}
return 0;
}
这题是典型的线段树区间更新,不过有一个点需要注意,在建树之间需要把数据离散化,因为数据范围过大,直接建树会超内存,不信可以试试
这里首先讲下如何把数据进行离散化。