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
",cnt);
90     }
91     return 0;
92 }
原文地址:https://www.cnblogs.com/ZERO-/p/9729198.html