题目大意
给出n个区间,n<=10000, 依次将每个区间涂上不同 的颜色,问最后还能看见多少种颜色
输入
第一行是一个整数t表示t组数据
对于每组数据:
第1行是n表示有n个区间
接下来n行2个整数L,R表示区间(1<=L<=R<=10000000)
输出
对于每组数据输出一个整数,一共t行
样例输入
1
5
1 4
2 6
8 10
3 4
7 10
样例输出
4
题解
线段树加离散化。不会unique和lowerbound的蒟蒻就只会手动了(然后我果然二分写炸了)之前更新节点信息写错了,瞄了一眼老师的代码就知道我弱智了。
代码
#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
using namespace std;
#define lc (o<<1)
#define rc (o<<1|1)
#define mid (l+r>>1)
const int N=1e6+10;
int n,top,sz;
int hx[N];
int L[N];
int R[N];
int tr[N];//之前数组开的1e4<<2,RE了
set<int>s;
inline void push_down(int o,int l,int r)
{
if(tr[o]==0)return;
tr[lc]=tr[rc]=tr[o];
tr[o]=0;
}
void build(int o,int l,int r)
{
if(l==r)
{
tr[o]=0;
return;
}
build(lc,l,mid);build(rc,mid+1,r);
}
void update(int o,int l,int r,int nl,int nr,int id)
{
if(l==nl&&r==nr)
{
tr[o]=id;
return;
}
push_down(o,l,r);
if(nr<=mid)update(lc,l,mid,nl,nr,id);
else if(nl>mid)update(rc,mid+1,r,nl,nr,id);
else update(lc,l,mid,nl,mid,id),update(rc,mid+1,r,mid+1,nr,id);
}
void query(int o,int l,int r)
{
if(tr[o]>0)
{
s.insert(tr[o]);
return;
}
if(l==r)return;
push_down(o,l,r);
query(lc,l,mid);query(rc,mid+1,r);
}
int bs(int x)
{
int l=1;int r=sz;
while(l<=r)
{
if(hx[mid]==x)return mid;
else if(hx[mid]>x)r=mid;
else l=mid+1;
}
}
int main()
{
//freopen("in.txt","r",stdin);
int t,le,ri;
scanf("%d",&t);
while(t--)
{
top=0;
s.clear();
int x,y;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&L[i],&R[i]);
hx[++top]=L[i];hx[++top]=R[i];
}
sort(hx+1,hx+top+1);
sz=1;
for(int i=2;i<=top;i++)
if(hx[i]!=hx[i-1])hx[++sz]=hx[i];
sort(hx+1,hx+sz+1);
build(1,1,sz);
for(int i=1;i<=n;i++)
{
int idx=bs(L[i]);
int idy=bs(R[i]);
update(1,1,sz,idx,idy,i);
}
query(1,1,sz);
printf("%d\n",s.size());
}
return 0;
}