zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSAS 系列
    微软BI 之SSRS 系列
    微软BI 之SSRS 系列
    配置 SQL Server Email 发送以及 Job 的 Notification通知功能
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4725051.html
Copyright © 2011-2022 走看看