POJ 2528-Mayor's posters --- 线段树+离散化
大致题意:
有一面墙,被等分为1QW份,一份的宽度为一个单位宽度。现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW。后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报。现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(说明:经过测试得出结论,如果题意是说看见至少一边或者全部那么数据没有问题,如果是说包括只看见中间一部分,那么数据就有问题,也许是我题意没看清,英文不行。)
数据离散化例子:
有一条1到10的数轴(长度为9),给定4个区间[2,4] [3,6] [8,10] [6,9],覆盖关系就是后者覆盖前者,每个区间染色依次为 1 2 3 4。
现在我们抽取这4个区间的8个端点,2 4 3 6 8 10 6 9
然后删除相同的端点,这里相同的端点为6,则剩下2 4 3 6 8 10 9
对其升序排序,得2 3 4 6 8 9 10
然后建立映射
2 3 4 6 8 9 10
↓ ↓ ↓ ↓ ↓ ↓ ↓
1 2 3 4 5 6 7
那么新的4个区间为 [1,3] [2,4] [5,7] [4,6],覆盖关系没有被改变。新数轴为1到7,即原数轴的长度从9压缩到6,显然构造[1,7]的线段树比构造[1,10]的线段树更省空间,搜索也更快,但是求解的结果却是一致的。
View Code
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #define N 200001 6 #define M 10000001 7 using namespace std; 8 struct node{ 9 int lef,rig; 10 int mrk; 11 }p[3*N]; 12 13 int dis[M],flag[N],res[N],gra[M][2]; 14 void tree(int ind,int st,int ed) 15 { 16 p[ind].lef=st; 17 p[ind].rig=ed; 18 p[ind].mrk=0; 19 if(st==ed) 20 { 21 return ; 22 } 23 int mid=(st+ed)>>1; 24 tree(ind<<1,st,mid); 25 tree(ind<<1|1,mid+1,ed); 26 } 27 void update(int ind,int st,int ed,int val) 28 { 29 if(p[ind].lef==st&&p[ind].rig==ed) 30 { 31 p[ind].mrk=val; 32 return ; 33 } 34 if(p[ind].mrk!=-1) 35 { 36 p[ind<<1].mrk=p[ind<<1|1].mrk=p[ind].mrk; 37 p[ind].mrk=-1; 38 } 39 int mid=(p[ind].lef+p[ind].rig)>>1; 40 if(st>mid) 41 { 42 update(ind<<1|1,st,ed,val); 43 } 44 else if(ed<=mid) 45 { 46 update(ind<<1,st,ed,val); 47 } 48 else 49 { 50 update(ind<<1,st,mid,val); 51 update(ind<<1|1,mid+1,ed,val); 52 } 53 } 54 int seach(int ind) 55 { 56 if(p[ind].mrk==0) 57 { 58 return 0; 59 } 60 else if(p[ind].mrk>0) 61 { 62 if(flag[p[ind].mrk]==0) 63 { 64 flag[p[ind].mrk]=1; 65 return 1; 66 } 67 return 0; 68 } 69 else 70 { 71 return seach(ind<<1)+seach(ind<<1|1); 72 } 73 } 74 int main() 75 { 76 int i,t,n,pt,qt; 77 scanf("%d",&t); 78 while(t--) 79 { 80 scanf("%d",&n); 81 memset(dis,0,sizeof(dis)); 82 memset(flag,0,sizeof(flag)); 83 for(i=1,pt=0;i<=n;i++) 84 { 85 scanf("%d%d",&gra[i][0],&gra[i][1]); 86 if(dis[gra[i][0]]==0) 87 { 88 res[pt++]=gra[i][0]; 89 dis[gra[i][0]]=1; 90 } 91 if(dis[gra[i][1]]==0) 92 { 93 res[pt++]=gra[i][1]; 94 dis[gra[i][1]]=1; 95 } 96 } 97 sort(res,res+pt); 98 for(i=0,qt=1;i<pt;i++) 99 { 100 dis[res[i]]=qt++; 101 } 102 tree(1,1,qt-1); 103 for(i=1;i<=n;i++) 104 { 105 update(1,dis[gra[i][0]],dis[gra[i][1]],i); 106 } 107 printf("%d\n",seach(1)); 108 } 109 return 0; 110 }