poj 2528 线段树 离散化的小技巧
题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报
思路:直接搞超时+超内存,需要离散化。
离散化简单的来说就是只取我们需要的值来
用,比如说区间[1000,2000],[1990,2012]
我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只需要
1000,1990,2000,2012就够了,将其分别映射到0,1,2,3,在于复杂度就大大的降下来了
所以离散化要保存所有需要用到的值,排序后,分别映射到1~n,这样复杂度就会小很多很多
而这题的难点在于每个数字其实表示的是一个单位长度(并且一个点),这样普通的离散化会造成许多错误
给出下面两个简单的例子应该能体现普通离散化的缺陷:
1-10 1-4 5-10
1-10 1-4 6-10
为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]
如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8 #include<vector> 9 #include<cstring> 10 #include<stack> 11 #include<cmath> 12 #include<queue> 13 #define clc(a,b) memset(a,b,sizeof(a)) 14 //#include <bits/stdc++.h> 15 using namespace std; 16 #define LL long long 17 const int maxn=100000; 18 int vis[maxn<<2]; 19 int ans=0; 20 int x[maxn]; 21 int hashh[maxn<<2]; 22 struct node 23 { 24 int l,r; 25 } q[maxn]; 26 27 void pushdown(int rt) 28 { 29 if(vis[rt]!=-1) 30 { 31 vis[rt<<1]=vis[rt<<1|1]=vis[rt]; 32 vis[rt]=-1; 33 } 34 } 35 36 void update(int L,int R,int c,int l,int r,int rt) 37 { 38 if(L<=l&&R>=r) 39 { 40 vis[rt]=c; 41 return; 42 } 43 pushdown(rt); 44 int m=(l+r)>>1; 45 if(L<=m) update(L,R,c,l,m,rt<<1); 46 if(R>m) update(L,R,c,m+1,r,rt<<1|1); 47 } 48 49 void query(int l,int r,int rt) 50 { 51 if(vis[rt]!=-1) 52 { 53 if(!hashh[vis[rt]]) 54 ans++; 55 hashh[vis[rt]]=1; 56 return; 57 } 58 if(l==r) 59 return; 60 int m=(l+r)>>1; 61 query(l,m,rt<<1); 62 query(m+1,r,rt<<1|1); 63 } 64 65 int main() 66 { 67 int n,t; 68 scanf("%d",&t); 69 while(t--) 70 { 71 int cnt=0; 72 scanf("%d",&n); 73 for(int i=0; i<n; i++) 74 { 75 scanf("%d%d",&q[i].l,&q[i].r); 76 x[cnt++]=q[i].l,x[cnt++]=q[i].r; 77 } 78 sort(x,x+cnt); 79 int m=1; 80 for(int i=1; i<cnt; i++) 81 { 82 if(x[i]!=x[i-1]) 83 x[m++]=x[i]; 84 } 85 for(int i=m-1; i>=1; i--) 86 if(x[i]!=x[i-1]+1) 87 x[m++]=x[i-1]+1; 88 sort(x,x+m); 89 clc(vis,-1); 90 for(int i=0; i<n; i++) 91 { 92 int l=lower_bound(x,x+m,q[i].l)-x; 93 int r=lower_bound(x,x+m,q[i].r)-x; 94 update(l,r,i,0,m,1); 95 } 96 clc(hashh,0); 97 ans=0; 98 query(0,m,1); 99 printf("%d\n",ans); 100 } 101 return 0; 102 }