NC16649 [NOIP2005]校门外的树

题目

题目描述

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

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

输入描述

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

输出描述

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

示例1

输入

  1. 500 3
  2. 150 300
  3. 100 200
  4. 470 471

输出

  1. 298

题解

数据范围一(原题范围):$L \leq 10^4 $ ,$ M \leq 10^2$

思路

知识点:差分。

数组直接模拟整个区间,进行差分。

时间复杂度 \(O(L+M)\)

空间复杂度 \(O(L)\)

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int vis[10007];///模拟整个区间
  4. int main(){
  5. int L,M;
  6. cin>>L>>M;
  7. for(int i = 0;i<M;i++){
  8. int l,r;
  9. cin>>l>>r;
  10. vis[l]++;
  11. vis[r+1]--;///差分
  12. }
  13. int a = 0,ans = 0;
  14. for(int i = 0;i<=L;i++){
  15. a += vis[i];///前缀和
  16. if(!a) ans++;///加完之后是0,那说明此处无遮盖
  17. }
  18. cout<<ans<<'\n';
  19. return 0;
  20. }

数据范围二(加强): \(L \leq 10^5\) , \(M \leq 10^5\)

思路

知识点:离散化。

端点代替区间,合并区间后求长与总长相减。

时间复杂度 \(O(MlogM)\)

空间复杂度 \(O(M)\)

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. struct qj{
  4. int l,r;
  5. }a[100007];
  6. bool cmp(qj a,qj b){
  7. return a.l == b.l?a.r<b.r:a.l<b.l;
  8. }
  9. int main(){
  10. int L,M;
  11. cin>>L>>M;
  12. for(int i = 0;i<M;i++){
  13. cin>>a[i].l>>a[i].r;
  14. }
  15. sort(a,a+M,cmp);///按左端点从小到大,再按右端点从小到大
  16. int cnt = 0;///记录合并区间长度
  17. int l = a[0].l,r = a[0].r;///记录初始合并区间
  18. for(int i = 1;i<M;i++){
  19. if(a[i].l<=r) r = max(r,a[i].r);
  20. ///当前区间左端点小于等于此合并区间的右端点(不是上个区间的右端点,这里错了tmd)(因为排序,当前区间左端点不可能小于上一个区间左端点)
  21. ///那么合并区间的右端点为自己和当前区间右端点的最大值
  22. else{
  23. cnt+=r-l+1;
  24. l = a[i].l;
  25. r = a[i].r;
  26. }///合并结束更新
  27. }
  28. cnt+=r-l+1;
  29. cout<<L-cnt+1<<'\n';///L+1是总端点数
  30. }

数据范围三(再加强): \(L \leq 10^9\) , \(M \leq 10^5\)

思路

知识点:离散化+差分。

已经无法用数组模拟区间,考虑模拟端点的差分值,累加目标区间长度。

时间复杂度 \(O(MlogM)\)

空间复杂度 \(O(M)\)

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. struct diff{
  4. int pos;
  5. int num;
  6. }delta[100007];///记录特定端点代替整个区间,达到满足空间要求
  7. bool cmp(diff a,diff b){
  8. return a.pos==b.pos?a.num<b.num:a.pos<b.pos;
  9. }
  10. int main(){
  11. std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  12. int L,M;
  13. cin>>L>>M;
  14. for(int i = 0;i<M;i++){
  15. int x,y;
  16. cin>>x>>y;
  17. delta[i].pos = x;///记录左端点
  18. delta[i].num = 1;
  19. delta[i+M].pos = y+1;///记录右端点,因为差分所以y+1
  20. delta[i+M].num = -1;
  21. }
  22. sort(delta,delta+2*M,cmp);///根据左端点从小到大排序,先负再正
  23. int a = 0,cnt = 0;
  24. for(int i = 0;i<2*M;i++){
  25. a += delta[i].num;
  26. if(a == 1 && delta[i].num == 1){///此时pos是0区域的右端点+1位置,上一个pos即左端点位置
  27. cnt+=delta[i].pos - delta[i-1].pos;///相减即为区间长度
  28. }
  29. }
  30. if(!a) cnt+=L-delta[2*M-1].pos+1;
  31. cout<<cnt<<'\n';
  32. return 0;
  33. }

NC16649 [NOIP2005]校门外的树的更多相关文章

  1. P1047 校门外的树

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

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

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

  3. C语言 · 校门外的树

    算法提高 校门外的树   时间限制:1.0s   内存限制:256.0MB      问题描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的 ...

  4. >题解< 校门外的树

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

  5. 洛谷P1047 校门外的树

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

  6. 洛谷——P1047 校门外的树

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

  7. luogu P1047 校门外的树 x

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

  8. Vijos1448校门外的树 题解

    Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...

  9. OpenJudge计算概论-校门外的树

    /*======================================================================== 校门外的树 总时间限制: 1000ms 内存限制: ...

随机推荐

  1. 2022.02.21 UB

    2022.02.21 UB 参考资料: https://zhuanlan.zhihu.com/p/141467895 https://blog.csdn.net/ghscarecrow/article ...

  2. Vue 组件实战

    目录 Vue 组件 axios实现数据请求 计算属性 案例一:首字母大写 案例二:过滤案例 监听属性 局部组件 全局组件 组件通信之父传子 组件通信之子传父 ref属性(组件间通信) 普通标签使用 组 ...

  3. SSM框架中返回的是字符串还是页面跳转的问题

    如果你在控制器前的注解是@RestController的话,将返回controller方法指定的String值,@RestController注解相当于@ResponseBody和@Controlle ...

  4. junethack使用指南

    本文面向有志于参加Nethack六月衍生大赛,且具有一定英文水平的玩家. 首先,在Junethack服务器页面挑一个在线服务器的网站,个人推荐 hardfought.org,因为访问速度较快. 然后, ...

  5. .net core JWT验证,HttpContext.User为空的问题

    这几天在学习张老师.net core教程JWT部分,链接 https://mp.weixin.qq.com/s/7135y3MkUlPIp-flfwscig 教程使用的.net core 2.2, 在 ...

  6. 定位、z-index、JavaScript变量和数据类型

    溢出属性 # 文本内容超出了标签的最大范围 overflow: hidden; 直接隐藏文本内容 overflow: auto\scroll; 提供滚动条查看 # 溢出实战案例 div { overf ...

  7. 设计模式---单例模式,pickle模块

    设计模式---单例模式 简介 单例模式(Singleton Pattern) 是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实 例存在.当你希望在整个系统中,某个类只能出现一个实例时 ...

  8. grpc-java源码环境编译

    1. Clone 1.1 git clone https://github.com/grpc/grpc-java.git 1.2 idea 打开grpc-java工程 2.compile 2.1 ja ...

  9. SSH管理多密钥

    生成密钥对 ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # 默认情况下在~/.ssh目录下生成id_rsa和id_r ...

  10. Mybatis-Plus乐观锁Version

    实现原理 取出记录时,获取当前version更新时,带上这个version执行更新时, set version = newVersion where version = oldVersion如果ver ...