• poj 2528(线段树+离散化) 市长的海报


    http://poj.org/problem?id=2528

    题目大意是市长竞选要贴海报,给出墙的长度和依次张贴的海报的长度区间(参考题目给的图),问最后你能看见的海报有几张

    就是有的先贴的海报可能会被后贴的海报完全盖住,那就看不见了

    这里就非常抽象的区间更新,墙的长度为建立线段树的总区间,每贴一张海报代表将这个区间的颜色涂为相应的,每张海报的颜色当然

    都不相同,求最后又多少种颜色就行,但这里还要用到基础的离散化

    离散化是把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率。

    简单点说,假设区间长度有一亿甚至跟多,但是区间里具体的值却最多只用到了一百万,且不说能否开那么大的数组,也造成了

    内存的浪费,所以用离散化来节省不必要的浪费

    举这个题目的样例来说(前三个)

    如果只是改变区间1 7    2 6    8 10的颜色,那么剩下的数字并没有用到

    那么我们将这些数字排序,x[1]=1 x[2]=2 x[3]=6 x[4]=7 x[5]=8 x[6]=10

    但是如果每个相邻的差值大于1的时候要插入一个数(就插入x[i]-1好了),

    (如果不插的话

     假设三张海报为:1 10   1 4   6 10

    离散化时 x[1] = 1   x[2]=4  X[3]=6   X[4]=10
    第一张海报时:墙的1~4被染为1;
    第二张海报时:墙的1~2被染为2,3~4仍为1;
    第三张海报时:墙的3~4被染为3,1~2仍为2。
    最终,第一张海报就显示被完全覆盖了,然后输出2,但是正确答案明显是3)

    插入后新的排序为x[1]=1 x[2]=2 x[3]=5 x[4]=6 x[5]=7 x[6]=8 x[7]=9 x[8]=10

    然后以这个新的长度为8的数组区间建树就好

    code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct point {
     7     int l,r;
     8     int mark,sum;
     9 };
    10 point tree[10001*4*4],num[10001*4];
    11 int ans,res[10001*4],visit[10001*4];
    12 void build(int i,int left,int right)
    13 {
    14     tree[i].l=left,tree[i].r=right;
    15     tree[i].mark=tree[i].sum=0;
    16     if (left==right) return ;
    17     int mid=(left+right)/2;
    18     build(i*2,left,mid);
    19     build(i*2+1,mid+1,right);
    20 }
    21 void update(int i,int left,int right,int val)
    22 {
    23     if (left<=tree[i].l&&tree[i].r<=right){tree[i].mark=tree[i].sum=val;return ;}
    24     if (tree[i].mark)
    25     {
    26         tree[i*2].mark=tree[i*2+1].mark=tree[i].mark;
    27         tree[i*2].sum=tree[i*2+1].sum=tree[i].mark;
    28         tree[i].mark=0;
    29     }
    30     int mid=(tree[i].r+tree[i].l)/2;
    31     if (left>mid) update(i*2+1,left,right,val);
    32     else if (right<=mid) update(i*2,left,right,val);
    33     else
    34     {
    35         update(i*2,left,mid,val);
    36         update(i*2+1,mid+1,right,val);
    37     }
    38 }
    39 int find(int i)
    40 {
    41     if (tree[i].l==tree[i].r)
    42     {
    43         if (!visit[tree[i].sum])
    44         {
    45            visit[tree[i].sum]=1;
    46            ++ans;
    47         }
    48         return ans;
    49     }
    50     if (tree[i].mark)
    51     {
    52         tree[i*2].mark=tree[i*2+1].mark=tree[i].mark;
    53         tree[i*2].sum=tree[i*2+1].sum=tree[i].mark;
    54         tree[i].mark=0;
    55     }
    56     find(i*2);
    57     find(i*2+1);
    58 }
    59 int main()
    60 {
    61     int t,i,n,tn,tn1,powr,powl;
    62     scanf("%d",&t);
    63 
    64         if (t==0) return 0;
    65         while (t--)
    66         {
    67             res[0]=0;
    68             scanf("%d",&n);
    69             for (i=1;i<=n;i++)
    70             {
    71                scanf("%d %d",&num[i].l,&num[i].r);
    72                if (num[i].l>num[i].r) swap(num[i].l,num[i].r);
    73                res[++res[0]]=num[i].l;
    74                res[++res[0]]=num[i].r;
    75             }
    76             sort(res+1,res+res[0]+1);//离散化
    77             tn1=tn=unique(res+1,res+res[0]+1)-res;
    78             for (i=2;i<tn;i++)//插入数
    79                if (res[i]-res[i-1]>1)
    80                   res[tn1++]=res[i]-1;
    81             res[0]=tn1-1;
    82             sort(res+1,res+res[0]+1);
    83             build(1,1,res[0]);//以新的区间建树
    84             for (i=1;i<=n;i++)
    85             {
    86                 powl=lower_bound(res+1,res+1+res[0],num[i].l)-res;
    87                 powr=lower_bound(res+1,res+1+res[0],num[i].r)-res;
    88                 update(1,powl,powr,i);
    89             }
    90             ans=0;
    91             memset(visit,0,sizeof(visit));
    92             visit[0]=1;
    93             printf("%d
    ",find(1));
    94         }
    95 
    96     return 0;
    97 }
  • 相关阅读:
    程序员优化程序流程
    iOS开发优化的25个方案
    彻底解决_OBJC_CLASS_$_某文件名", referenced from:问题转
    svn服务器搭建与配置
    mac 显示隐藏文件夹
    HDU 2276 Kiki & Little Kiki 2 矩阵构造
    HDU 3306 Another kind of Fibonacci ---构造矩阵***
    HDU 1575 Tr A----矩阵相乘题。
    矩阵的模板----
    HDU 1757 矩阵求第n的递推式
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4725051.html
Copyright © 2020-2023  润新知