zoukankan      html  css  js  c++  java
  • POJ 2808 校门外的树(线段树入门)

    题目描述
    某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
    马路上有一些区域要用来建地铁,这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。
    你的任务是计算将这些树都移走后,马路上还有多少棵树。
    输入
    输入的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点 和终止点的坐标。
    输出
    输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
    样例输入
    500 3150 300100 200470 471
    样例输出
    298
    线段的区间覆盖,我把这道题当作自己线段树的入门题。线段树的核心思想是以空间换时间。以4倍的空间复杂度来将O(n)的算法优化成O(logn)。
    如果现在的节点在树的数组中的下标为now,则它的左儿子的下标就是now*2,右儿子的下标就是now*2+1。
    如果现在节点所代表的区间范围是[l,r],则它的左儿子代表的区间范围是[l,mid],右儿子是[mid+1,r](mid=(l+r)/2);
    建树的时候按照先序遍历的顺序来建树。
    代码如下:
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 #define MAXN 40040
     5 #define inf 0x3f3f3f3f
     6 struct segTree
     7 {
     8     int l,r,sum;
     9 }tree[MAXN];
    10 void buildTree (int now,int ll,int rr)
    11 {
    12     tree[now].l=ll;
    13     tree[now].r=rr;
    14     if (ll==rr)//如果当前区间长度为1
    15     {
    16         tree[now].sum=1;//这个区间最开始只有1棵树
    17         return;//不写return会炸...
    18     }
    19     int mid=(ll+rr)/2;
    20     int lch=now*2,rch=now*2+1;
    21     buildTree(lch,ll,mid);//建左子树
    22     buildTree(rch,mid+1,rr);//建右子树
    23 tree[now].sum=tree[lch].sum+tree[rch].sum;
    24 //父亲节点树木是左右子节点的树木个数的和
    25 }
    26 void update (int now,int ll,int rr,int x,int y)
    27 {
    28 if (ll>y||rr<x||tree[now].sum==0) 
    29 //当[x,y]与当前区间[ll,rr]没有交集时,或此区间的树都已经被拔光了
    30 return ;
    31     if (x<=ll&&y>=rr) 
    32     {
    33         tree[now].sum=0;//将此区间树拔光
    34         return ;
    35     }
    36     int mid=(ll+rr)/2;
    37     int lch=now*2,rch=now*2+1;
    38     update(lch,ll,mid,x,y);//二分寻找[ll,rr],使其与[x,y]有交集
    39     update(rch,mid+1,rr,x,y);
    40     tree[now].sum=tree[lch].sum+tree[rch].sum;
    41 }
    42 int L,M;
    43 int main()
    44 {
    45     //freopen("de.txt","r",stdin);
    46     scanf("%d%d",&L,&M);
    47     buildTree(1,1,1+L);
    48     for (int i=0;i<M;++i)
    49     {
    50         int left,right;
    51         scanf("%d%d",&left,&right);
    52         update(1,1,1+L,left+1,right+1);
    53     }
    54     printf("%d
    ",tree[1].sum);
    55     return 0;
    56 }
  • 相关阅读:
    html JS 打开本地程序及文件
    [转]jquery mobile中redirect重定向问题
    kafka中broker、producer、consumer主要配置参数说明
    手写一个LruCache
    ES发布时max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 错误
    UML类图
    JVM调优总结
    JVM学习系列(五) 常见的JVM参数
    JVM学习系列(四) 相关概念
    JVM学习系列(三) 虚拟机监控相关
  • 原文地址:https://www.cnblogs.com/agenthtb/p/5867377.html
Copyright © 2011-2022 走看看