Vijos P1103 校门外的树【线段树,模拟】

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

校门外的树

描述

某校大门外长度为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 }

 

目录
相关文章
|
5月前
|
存储 C++
【C++从0到王者】第三十站:二叉树的非递归遍历
【C++从0到王者】第三十站:二叉树的非递归遍历
22 0
|
7月前
校门外的树(三种解法,非直接暴力)
校门外的树(三种解法,非直接暴力)
|
8月前
|
算法
【过河卒】回溯算法保姆式解题
【过河卒】回溯算法保姆式解题
48 0
|
11月前
|
机器学习/深度学习 安全
洛谷P2245 星际导航(kruskal重构树)
洛谷P2245 星际导航(kruskal重构树)
98 0
|
算法
算法竞赛题解:校门外的树
NOIP2005 普及组:校门外的树
200 0
|
机器学习/深度学习
带你轻松拿捏N皇后问题
要求任何两个皇后不同行、不同列,也不在同一 条斜线上
100 0
带你轻松拿捏N皇后问题
LeetCode每日一题(11)——太平洋大西洋水流问题(递归,深度优先遍历实例)
大西洋太平洋水流问题 1.题目 2.示例 3.思路 理解题目 解题思路 4.代码
109 0
LeetCode每日一题(11)——太平洋大西洋水流问题(递归,深度优先遍历实例)
|
机器学习/深度学习 算法
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
|
存储 算法
学会二叉树不知道干啥?二叉树的深度优先搜索和广度优先搜索,我要打十个乃至二十个(打开你的LeetCode撸起来)学练并举
学会二叉树不知道干啥?二叉树的深度优先搜索和广度优先搜索,我要打十个乃至二十个(打开你的LeetCode撸起来)学练并举
学会二叉树不知道干啥?二叉树的深度优先搜索和广度优先搜索,我要打十个乃至二十个(打开你的LeetCode撸起来)学练并举