zoukankan      html  css  js  c++  java
  • POJ 2528.Mayor's posters-线段树(成段替换、离散数据、简单hash)

    POJ2528.Mayor's posters

    这道题真的是线段数的经典的题目,因为数据很大,直接建树的话肯定不可以,所以需要将数据处理一下,没有接触离散化的时候感觉离散化这个东西相当高级,其实在不知道离散化是什么东西之前,就已经用过这种东西了,只是不知道叫什么。关于离散化,就是根据数的相对大小对他们进行映射,用小的数来表示他们。所以要先排序,然后去重,然后操作就可以。有排序版的离散化和STL版的离散化(自己起的名字 。。。),代码里写的是排序版的,就是for循环遍历的时候,和身边的数比较一下是否是相同的数,然后操作。具体的不介绍,自行百度吧。

    这道题就是贴海报,只与两个边界值有关系,但是如果两个数中间的间隔大于1的话,中间应该加数,否则新的点覆盖到上面的时候,就会出错。举个例子,假设我点为1,2,7,10,我离散化映射为0,1,2,3,区间操作为(1,10),(1,2),(7,10),因为线段树是对点进行维护,所以是对点染色,对点染色的话,就将两个点都改变了,所以1,2,7,10都变了颜色,只能看到2种,但是正确的应该是3种,(2,7)还能看到,所以需要在间隔大于1的时候中间加点,这样就不会出错了。映射的时候二分查找就会快很多,其他的就没什么了。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<map>
     9 #include<stack>
    10 using namespace std;
    11 typedef long long ll;
    12 const int maxn=1e5+10;
    13 const int inf=0x3f3f3f3f;
    14 const double eps=1e-5;
    15 #define lson l,m,rt<<1
    16 #define rson m+1,r,rt<<1|1
    17 int col[maxn<<2],hash[maxn<<2],a[maxn],li[maxn],ri[maxn],cnt;
    18 void pushdown(int rt)
    19 {
    20     if(col[rt]!=-1){
    21         col[rt<<1]=col[rt<<1|1]=col[rt];
    22         col[rt]=-1;
    23     }
    24 }
    25 void update(int L,int R,int c,int l,int r,int rt)
    26 {
    27     if(L<=l&&r<=R){
    28         col[rt]=c;
    29         return ;
    30     }
    31 
    32     pushdown(rt);
    33     int m=(l+r)>>1;
    34     if(L<=m) update(L,R,c,lson);
    35     if(R> m) update(L,R,c,rson);
    36 }
    37 void query(int l,int r,int rt)
    38 {
    39     if(col[rt]!=-1){
    40         if(hash[col[rt]]==0) cnt++;
    41         hash[col[rt]]=1;
    42         return ;
    43     }
    44 
    45     if(l==r) return ;
    46     int m=(l+r)>>1;
    47     query(lson);
    48     query(rson);
    49 }
    50 int reflect(int key,int n,int a[])
    51 {
    52     int l=0,r=n-1;
    53     while(l<=r){
    54         int m=(l+r)>>1;
    55         if(a[m]==key) return m;
    56         if(a[m]< key) l=m+1;
    57         else r=m-1;
    58     }
    59     return -1;
    60 }
    61 int main()
    62 {
    63     int t,n;
    64     scanf("%d",&t);
    65     while(t--){
    66         scanf("%d",&n);
    67         int h=0,k=1;
    68         memset(col,-1,sizeof(col));
    69         memset(hash,0,sizeof(hash));
    70         for(int i=0;i<n;i++){
    71             scanf("%d%d",&li[i],&ri[i]);
    72             a[h++]=li[i];a[h++]=ri[i];
    73         }
    74         sort(a,a+h);
    75         for(int i=1;i<h;i++){
    76             if(a[i]!=a[i-1]) a[k++]=a[i];
    77         }
    78         for(int i=k-1;i>0;i--){
    79             if(a[i]!=a[i-1]+1) a[k++]=a[i]+1;
    80         }
    81         sort(a,a+k);
    82         for(int i=0;i<n;i++){
    83             int l=reflect(li[i],k,a);
    84             int r=reflect(ri[i],k,a);
    85             update(l,r,i,0,k,1);
    86         }
    87         cnt=0;
    88         query(0,k,1);
    89         printf("%d
    ",cnt);
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    图像处理之优化---任意半径局部直方图类算法在PC中快速实现的框架
    新的验证方式---短信验证和语言验证
    习武 之路---通背拳和苗刀!
    模式识别之Shape Context---利用Shape Context进行形状识别
    ELK 部署
    rsync实现文件备份同步
    oracle-3-子查询和常用函数
    oracle-2中commit 详解
    使用nginx绑定域名,代理gitlab
    Linux Crontab 安装使用详细说明
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9729198.html
Copyright © 2011-2022 走看看