线段树和离散化。
1e7内存肯定存不下,用离散化离散出各店横坐标,进行排序。
更新n次,更新每种颜色。
用二分查找找到每种颜色两端的序号。
直接把坐标作为点。
query()时更新各个线段的颜色,记录答案。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <iostream>
using namespace std;
#define maxn 21000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node
{
int l,r,id;
}t[maxn];
int save[maxn<<2];
int cov[maxn<<4];
int ans,tail,n;
set<int>ex;
int bin(int key)
{
int l=0,r=tail+1;
while(r-l>1)
{
int mid=(l+r)>>1;
if(save[mid]<=key)
l=mid;
else r=mid;
}
return l;
}
void pushdown(int num,int s,int e)
{
if(cov[num]!=0)
{
cov[num<<1]=cov[num<<1|1]=cov[num];
cov[num]=0;
}
}
void update(int l,int r,int rt,int s,int e,int val)
{
if(s<=l && e>=r)
{
cov[rt]=val;
return;
}
int m=(l+r)>>1;
pushdown(rt,l,r);
if(s<=m)
update(lson,s,e,val);
if(e>m)
update(rson,s,e,val);
}
void query(int l,int r,int rt)
{
if(cov[rt]!=0 || l==r)
{
if(ex.find(cov[rt])==ex.end())
{
ans++;
ex.insert(cov[rt]);
}
return;
}
int m=(l+r)>>1;
query(lson);
query(rson);
}
int main()
{
int cases;
scanf("%d",&cases);
while(cases--)
{
ex.clear();
memset(cov,0,sizeof(cov));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&t[i].l,&t[i].r);
t[i].id=i;
save[i*2]=t[i].r;
save[i*2-1]=t[i].l;
}
sort(save+1,save+1+2*n);
tail=unique(save+1,save+1+2*n)-save-1;
for(int i=1;i<=n;i++)
{
int s=bin(t[i].l);
int e=bin(t[i].r);
update(1,tail,1,s,e,t[i].id);
}
ans=0;
query(1,tail,1);
printf("%d\n",ans);
}
return 0;
}
/*
1
5
1 4
2 6
8 10
3 4
7 10
*/