zoukankan      html  css  js  c++  java
  • Vijos P1103 校门外的树【线段树,模拟】

    校门外的树

    描述

    某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

    由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。 已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

    格式

    输入格式

    输入的第一行有两个整数:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

    输出格式

    输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

    样例1

    样例输入1

    500 3
    150 300
    100 200
    470 471
    

    样例输出1

    298
    

    限制

    每个测试点1s

    来源

    NOIP2005普及组第二题

    题目链接:https://vijos.org/p/1103

    思路:我估计也是智障了,这题明显可以用模拟做,我TM竟然用线段树写,还RE了两发,数组开了四倍你还要我怎样,结果我开了八倍过了QAQ!

    下面给出线段树写法:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N=20010;
     4 int n,m,ans=1;
     5 struct Node
     6 {
     7     int l,r,sum;
     8 }tree[N<<2];
     9 inline void buildtree(int l,int r,int pos)
    10 {
    11     tree[pos].l=l;
    12     tree[pos].r=r;
    13     if(l==r)
    14     {
    15         tree[pos].sum=1;
    16         return;
    17     }
    18     int mid=(tree[pos].l+tree[pos].r)/2;
    19     buildtree(l,mid,pos*2);
    20     buildtree(mid+1,r,pos*2+1);
    21     tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;
    22 }
    23 inline int query(int l,int r,int pos)
    24 {
    25     if(tree[pos].l==l&&tree[pos].r==r)
    26         return tree[pos].sum;
    27     if(tree[pos].r<l||tree[pos].l>r)
    28         return 0;
    29     return query(l,r,pos*2)+query(l,r,pos*2+1);
    30 }
    31 inline void update(int l,int r,int pos)
    32 {
    33     if(tree[pos].l==l&&tree[pos].r==r)
    34     {
    35         tree[pos].sum=0;
    36         return;
    37     }
    38     if(tree[pos].l>r||tree[pos].r<l)
    39         return;
    40     update(l,r,pos*2);
    41     update(l,r,pos*2+1);
    42     tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;
    43 }
    44 int main()
    45 {
    46     cin>>n>>m;
    47     buildtree(1,n,1);
    48     for(int i=1;i<=m;i++)
    49     {
    50         int l,r;
    51         scanf("%d%d",&l,&r);
    52         if(!l)
    53             ans=0;
    54         update(!l?1:l,r,1);
    55     }
    56     cout<<query(1,n,1)+ans<<endl;
    57     return 0;
    58 }

    模拟做法:简单解释一下,做法就是在【0,r】我们全部赋值为1,然后for一遍删去重复部分,非常简单,智障的我开始没想到,但是如果这题L的数据是1000000,线段树依然是正解!QAQ

    下面给出模拟的代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N=10010;
     4 int a[N];
     5 int main()
     6 {
     7     int n,m;
     8     cin>>n>>m;
     9     for(int i=0;i<=n;i++)
    10         a[i]=1;
    11     for(int i=1;i<=m;i++)
    12     {
    13         int l,r;
    14         cin>>l>>r;
    15         for(int j=l;j<=r;j++)
    16         {
    17             a[j]=0;
    18         }
    19     }
    20     int sum=0;
    21     for(int i=0;i<=n;i++)
    22     {
    23         if(a[i])
    24             sum++;
    25     }
    26     cout<<sum<<endl;
    27     return 0;
    28 }
  • 相关阅读:
    模块二 GO语言进阶技术-panic函数、recover函数以及defer语句(上)
    模块二 GO语言进阶技术-错误处理(下)
    模块二 GO语言进阶技术-错误处理(上)
    模块二 GO语言进阶技术-if语句、for语句和switch语句
    模块二 GO语言进阶技术-GO语句及其执行规则(下)
    模块二 GO语言进阶技术-go语句及其执行规则(上)
    模块二 GO语言进阶技术-关于指针的有限操作
    模块二 GO语言进阶技术-接口类型的合理运用
    模块二 GO语言进阶技术-结构体及其方法的使用法门
    模块二 GO语言进阶技术-使用函数的正确姿势
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/7053654.html
Copyright © 2011-2022 走看看