poj2528(Mayor's posters)

题目地址:Mayor's posters

 

题目大意:

         给你t组测试数据,按照题目给出的区间顺序贴上海报,问你最后能够看到多少张海报(不被完全覆盖的海报是表示可以看的海报计数加一)。

 

解题思路:

        线段数+离散化(区间压缩映射)。

离散化 的大概思路 :   比如说给你一组 数据 1 4 1000 100000,  如果直接
                         开线段, 显然是浪费, 那么我们只要 进行 映射 :
                                   1      1  
                                   4      2
                              1000     3
                          100000     4
                         接下来 我们只要对 1 2 3 4 建立线段树就行了 只需要
                         [1,4]的区间     

离散化就相当于是先做映射,然后再建树。

墙上面的区间范围是1000W。 之间建树会内存超限,遍历二叉树搜索的时候也会时间超限,所以用到离散化,将范围缩小到海报数量1W*2. 然后在对各个区间编号。

需要注意是题目给出不相邻的端点离散后会变成相邻的端点,可能会造成错误,所以离散话的时候遇见相邻的端点时让hash阁一个点赋值。

 

我认为线段树的核心思想是尽量不往下搜索就不往下搜。

 

代码:

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cstdio>
  7 #include <string>
  8 #include <bitset>
  9 #include <vector>
 10 #include <queue>
 11 #include <stack>
 12 #include <cmath>
 13 #include <list>
 14 //#include <map>
 15 #include <set>
 16 using namespace std;
 17 /***************************************/
 18 #define ll long long
 19 #define PI 3.1415927
 20 /***************************************/
 21 
 22 const int M=20100;
 23 struct tree
 24 {
 25     int col;
 26     int left,right;
 27 } node[M*8];
 28 int p[M*2][2];
 29 int cnt,ce;
 30 int dis[10000100];
 31 void build__tree(int id,int l,int r)
 32 {
 33     int mid=(l+r)/2;
 34     node[id].left=l;
 35     node[id].right=r;
 36     node[id].col=0;
 37     if (l==r)
 38         return ;
 39     build__tree(id*2,l,mid);
 40     build__tree(id*2+1,mid+1,r);
 41 }
 42 void updata(int id,int l,int r,int v)
 43 {
 44     int mid=(node[id].left+node[id].right)/2;
 45     if (node[id].col)
 46        return;
 47     if (node[id].left==l&&node[id].right==r)
 48     {
 49         if (node[id].col==0)
 50         {
 51             node[id].col=1;
 52             cnt+=ce;
 53             ce=0;
 54         }
 55         return ;
 56     }
 57     if (r<=mid)
 58         updata(id*2,l,r,v);
 59     else if (l>mid)
 60         updata(id*2+1,l,r,v);
 61     else
 62     {
 63         updata(id*2,l,mid,v);
 64         updata(id*2+1,mid+1,r,v);
 65     }
 66     if (node[id*2].col==1&&node[id*2+1].col==1)
 67         node[id].col=1;
 68 }
 69 
 70 int main()
 71 {
 72     int cas;
 73     scanf("%d",&cas);
 74     while(cas--)
 75     {
 76         int n;
 77         scanf("%d",&n);
 78         int i,j;
 79         int xu[M*2],d=0;
 80         for(i=1;i<=n;i++)
 81         {
 82             scanf("%d%d",&p[i][0],&p[i][1]);
 83             xu[d++]=p[i][0];
 84             xu[d++]=p[i][1];
 85         }
 86         sort(xu,xu+d);
 87         int ncount=unique(xu,xu+d)-xu; //去重函数,头文件iostream.h
 88         int hash=0;
 89         for(i=0;i<ncount;i++)
 90         {
 91             dis[xu[i]]=++hash;
 92             if(xu[i]!=xu[i-1]+1&&i>0)
 93                 dis[xu[i]]=++hash;
 94         }
 95         build__tree(1,1,hash);
 96         cnt=0;
 97         for(i=n;i>=1;i--)
 98         {
 99             ce=1;
100             updata(1,dis[p[i][0]],dis[p[i][1]],1);
101         }
102         printf("%d\n",cnt);
103         memset(dis,0,sizeof(dis));
104     }
105     return 0;
106 }
107 /*
108 1
109 3
110 1 10
111 1 3
112 6 10
113 */
View Code

 

posted @ 2014-11-01 18:39  kinghold  Views(180)  Comments(0Edit  收藏  举报