zoukankan      html  css  js  c++  java
  • poj

    题意:在墙上贴海报,海报之间可以互相覆盖,问最后可以看见几张海报.

    思路:这题数据范围很大,直接搞容易超时+超内存,需要离散化.

    离散化简单来说就是只取我们需要用到的值来用,比如说区间[1000,2000],[1990,2012]

    我们用不到[-inf,999][1001,1989],[1991,1999],[2001,2011][2013,+inf]这些值,

    所以只需要1000,1990,2000,2012就够了,将其分别映射到0,1,2,3复杂度就会降下来.

    所以离散化就是保存所有需要用到的值,排序后,分别映射到1-n,就可以降低复杂度.

    但是这题每个数字其实表示一个单位长度(并非一个点),普通离散化会造成许多错误.

    比如:

    1-10 1-4 5-10
    1-10 1-4 6-10    

    离散化后都是[1,4][1,2][3,4]
    为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]
    如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.
    线段树功能:update:成段替换 query:简单hash

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 #define lson l,m,rt<<1
      6 #define rson m+1,r,rt<<1|1
      7 
      8 const int maxn = 11111;
      9 bool hash[maxn];
     10 int li[maxn],ri[maxn];
     11 int x[maxn*3];
     12 int col[maxn<<4];
     13 int cnt;
     14 
     15 void pushDown(int rt)
     16 {
     17     if(col[rt]!=-1)
     18     {
     19         col[rt<<1]=col[rt<<1|1]=col[rt];
     20         col[rt]=-1;
     21     }
     22 }
     23 
     24 void update(int L,int R,int c,int l,int r,int rt)
     25 {
     26     if(L<=l&&r<=R)
     27     {
     28         col[rt]=c;
     29         return;
     30     }
     31     pushDown(rt);
     32     int m=(l+r)>>1;
     33     if(L<=m) update(L,R,c,lson);
     34     if(m<R) update(L,R,c,rson);
     35 }
     36 
     37 void query(int l,int r,int rt)
     38 {
     39     if(col[rt]!=-1)
     40     {
     41         if(!hash[col[rt]]) cnt++;
     42         hash[col[rt]]=true;
     43         return;
     44     }
     45     if(l==r) return;
     46     int m=(l+r)>>1;
     47     query(lson);
     48     query(rson);
     49 }
     50 
     51 int Bin(int key,int n,int x[])
     52 {
     53     int l=0,r=n-1;
     54     while(l<=r)
     55     {
     56         int m=(l+r)>>1;
     57         if(x[m]==key) return m;
     58         if(x[m]<key) l=m+1;
     59         else r=m-1;
     60     }
     61     return -1;
     62 }
     63 
     64 int main()
     65 {
     66     //freopen("a.txt","r",stdin);
     67     int t,n;
     68     scanf("%d",&t);
     69     while(t--)
     70     {
     71         scanf("%d",&n);
     72         int nn=0;
     73         for(int i=0;i<n;i++)
     74         {
     75             scanf("%d%d",&li[i],&ri[i]);
     76             x[nn++]=li[i];
     77             x[nn++]=ri[i];
     78         }
     79         sort(x,x+nn);
     80         int m=1;
     81         for(int i=1;i<nn;i++) //去掉重复的
     82         {
     83             if(x[i]!=x[i-1]) x[m++]=x[i]; 
     84         }
     85         for(int i=m-1;i>0;i--) //如果间距大于1就插入任意一个数
     86         {
     87             if(x[i]!=x[i-1]+1) x[m++]=x[i-1]+1;
     88         }
     89         sort(x,x+m);
     90         memset(col,-1,sizeof(col));
     91         for(int i=0;i<n;i++) //二分查找左右边界在x中的位置
     92         {
     93             int l=Bin(li[i],m,x);
     94             int r=Bin(ri[i],m,x);
     95             update(l,r,i,0,m,1);//用第i种颜色更新
     96         }
     97         cnt=0;
     98         memset(hash,0,sizeof(hash));
     99         query(0,m,1);
    100         printf("%d
    ",cnt);
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    小白必读:闲话HTTP短连接中的Session和Token
    网络编程懒人入门(六):深入浅出,全面理解HTTP协议
    IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?
    致我们再也回不去的 Github ...
    了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化
    网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
    盘点微信的前世今生,微信成功的必然和偶然
    微信七年回顾:历经多少质疑和差评,才配拥有今天的强大
    写给小白的实时音视频技术入门提纲
    jenkins使用jacoco插件检测代码覆盖率(八)
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4718583.html
Copyright © 2011-2022 走看看