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 }

 

 

posted @ 2012-10-26 18:10  zyh123101  阅读(134)  评论(0编辑  收藏  举报