这题是我做区间更新离散化的第一题呀,对离散化的应用有了一定了了解,然后染色是区间更新另一种应用,最主要的是对col数组的处理。
先介绍最普通的离散化:
把可能出现的所有点排序,然后将该点再数组中的位置作为该点新的值。
用到stl包括:sort(a,a+n),low_bound(a,a+n,a[i]),unique(a,a+k)
注意一下就是
1.先排序,在去重。
2.要及时更新数组的大小,k=low_bound(a,a+k)-a;
这题得防止一种清况:
1-10 1-4 6-10
4,6之间在离散化之前可能出现一些空隙,在离散化后不会出现空隙,所以得在4,6之间加一个点就行了。
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 11111
#define INF 0xfffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,s,t) for(int i=s;i<=t;i++)
#define ull unsigned long long
#define ll long long
using namespace std;
int l[maxn],r[maxn],col[maxn<<4];
int a[maxn<<2],vis[maxn];
int ans;
void PushDown(int rt)
{
if(col[rt])
{
col[rt<<1]=col[rt];
col[rt<<1|1]=col[rt];
col[rt]=0;
}
}
void updata(int c,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
col[rt]=c;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(L<=m)
updata(c,L,R,lson);
if(R>m)
updata(c,L,R,rson);
}
void query(int l,int r,int rt)
{
if(col[rt])
{
if(!vis[col[rt]])
{
ans++;
vis[col[rt]]=1;
}
return ;
}
if(l==r)
{
return ;
}
int m=(l+r)>>1;
query(lson);
query(rson);
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int k=0;
for(int i=1; i<=n; i++)
{
scanf("%d%d",&l[i],&r[i]);
a[k++]=l[i];
a[k++]=r[i];
}
sort(a,a+k);
k=unique(a,a+k)-a;
int m=k;
for(int i=1; i<k; i++)
{
if(a[i]!=a[i-1]+1)
{
a[m++]=a[i-1]+1;
}
}
sort(a,a+m);
memset(col,0,sizeof(col));
for(int i=1; i<=n; i++)
{
l[i]=lower_bound(a,a+m,l[i])-a+1;
r[i]=lower_bound(a,a+m,r[i])-a+1;
updata(i,l[i],r[i],1,m,1);
}
ans=0;
memset(vis,0,sizeof(vis));
query(1,m,1);
printf("%d\n",ans);
}
return 0;
}