这题是我做区间更新离散化的第一题呀,对离散化的应用有了一定了了解,然后染色是区间更新另一种应用,最主要的是对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; }