POJ 2528.Mayor's posters-线段树(成段替换、离散数据、简单hash)
POJ2528.Mayor's posters
这道题真的是线段数的经典的题目,因为数据很大,直接建树的话肯定不可以,所以需要将数据处理一下,没有接触离散化的时候感觉离散化这个东西相当高级,其实在不知道离散化是什么东西之前,就已经用过这种东西了,只是不知道叫什么。关于离散化,就是根据数的相对大小对他们进行映射,用小的数来表示他们。所以要先排序,然后去重,然后操作就可以。有排序版的离散化和STL版的离散化(自己起的名字 。。。),代码里写的是排序版的,就是for循环遍历的时候,和身边的数比较一下是否是相同的数,然后操作。具体的不介绍,自行百度吧。
这道题就是贴海报,只与两个边界值有关系,但是如果两个数中间的间隔大于1的话,中间应该加数,否则新的点覆盖到上面的时候,就会出错。举个例子,假设我点为1,2,7,10,我离散化映射为0,1,2,3,区间操作为(1,10),(1,2),(7,10),因为线段树是对点进行维护,所以是对点染色,对点染色的话,就将两个点都改变了,所以1,2,7,10都变了颜色,只能看到2种,但是正确的应该是3种,(2,7)还能看到,所以需要在间隔大于1的时候中间加点,这样就不会出错了。映射的时候二分查找就会快很多,其他的就没什么了。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstdlib> 7 #include<queue> 8 #include<map> 9 #include<stack> 10 using namespace std; 11 typedef long long ll; 12 const int maxn=1e5+10; 13 const int inf=0x3f3f3f3f; 14 const double eps=1e-5; 15 #define lson l,m,rt<<1 16 #define rson m+1,r,rt<<1|1 17 int col[maxn<<2],hash[maxn<<2],a[maxn],li[maxn],ri[maxn],cnt; 18 void pushdown(int rt) 19 { 20 if(col[rt]!=-1){ 21 col[rt<<1]=col[rt<<1|1]=col[rt]; 22 col[rt]=-1; 23 } 24 } 25 void update(int L,int R,int c,int l,int r,int rt) 26 { 27 if(L<=l&&r<=R){ 28 col[rt]=c; 29 return ; 30 } 31 32 pushdown(rt); 33 int m=(l+r)>>1; 34 if(L<=m) update(L,R,c,lson); 35 if(R> m) update(L,R,c,rson); 36 } 37 void query(int l,int r,int rt) 38 { 39 if(col[rt]!=-1){ 40 if(hash[col[rt]]==0) cnt++; 41 hash[col[rt]]=1; 42 return ; 43 } 44 45 if(l==r) return ; 46 int m=(l+r)>>1; 47 query(lson); 48 query(rson); 49 } 50 int reflect(int key,int n,int a[]) 51 { 52 int l=0,r=n-1; 53 while(l<=r){ 54 int m=(l+r)>>1; 55 if(a[m]==key) return m; 56 if(a[m]< key) l=m+1; 57 else r=m-1; 58 } 59 return -1; 60 } 61 int main() 62 { 63 int t,n; 64 scanf("%d",&t); 65 while(t--){ 66 scanf("%d",&n); 67 int h=0,k=1; 68 memset(col,-1,sizeof(col)); 69 memset(hash,0,sizeof(hash)); 70 for(int i=0;i<n;i++){ 71 scanf("%d%d",&li[i],&ri[i]); 72 a[h++]=li[i];a[h++]=ri[i]; 73 } 74 sort(a,a+h); 75 for(int i=1;i<h;i++){ 76 if(a[i]!=a[i-1]) a[k++]=a[i]; 77 } 78 for(int i=k-1;i>0;i--){ 79 if(a[i]!=a[i-1]+1) a[k++]=a[i]+1; 80 } 81 sort(a,a+k); 82 for(int i=0;i<n;i++){ 83 int l=reflect(li[i],k,a); 84 int r=reflect(ri[i],k,a); 85 update(l,r,i,0,k,1); 86 } 87 cnt=0; 88 query(0,k,1); 89 printf("%d\n",cnt); 90 } 91 return 0; 92 }