 
            2023-10-30-LearningRecord
         
    
    
    
    刷题Day002
 
 
题目一
[NOIP2005 普及组] 校门外的树
题目描述
某校大门外长度为  的马路上有一排树,每两棵相邻的树之间的间隔都是  米。我们可以把马路看成一个数轴,马路的一端在数轴  的位置,另一端在  的位置;数轴上的每个整数点,即 ,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入格式
第一行有两个整数,分别表示马路的长度  和区域的数目 。
接下来  行,每行两个整数 ,表示一个区域的起始点和终止点的坐标。
输出格式
输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。
样例 #1
样例输入 #1
| 12
 3
 4
 
 | 500 3150 300
 100 200
 470 471
 
 | 
样例输出 #1
提示
【数据范围】
- 对于  的数据,保证区域之间没有重合的部分。
- 对于  的数据,保证 ,,。
【题目来源】
NOIP 2005 普及组第二题
解法一(状态数组):
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 
 | #define _CRT_SECURE_NO_WARNINGS#include<iostream>
 #include<vector>
 using namespace std;
 
 
 struct Volume {
 int startPoint;
 int endPoint;
 };
 
 
 int collectInput(vector<Volume>& volume) {
 int Length, areaAccount, leftPoint, rightPoint;
 scanf("%d %d", &Length, &areaAccount);
 Volume temp;
 for (int i = 0; i < areaAccount; i++) {
 scanf("\n%d %d", &leftPoint, &rightPoint);
 temp.startPoint = leftPoint;
 temp.endPoint = rightPoint;
 volume.push_back(temp);
 }
 return Length + 1;
 }
 
 int main() {
 
 vector<Volume> volume;
 
 vector<bool> statusArray;
 int Length = collectInput(volume);
 
 
 statusArray.resize(Length,true);
 
 for (int i = 0; i < volume.size(); i++) {
 for (int j = volume[i].startPoint; j <= volume[i].endPoint; j++) {
 statusArray[j] = false;
 }
 }
 
 int count = 0;
 for (int i = 0; i < statusArray.size(); i++) {
 if (statusArray[i]) {
 count++;
 }
 continue;
 }
 
 
 cout << count;
 
 return 0;
 }
 
 | 
解法二(线段树):
前置知识:[前缀和]前缀和
    