该题和 NC16649 校门外的树 这题类似
只不过校门外这道题由于数据范围比较小,所以直接“暴力”就可以过(当然,会写 “差分+前缀和” 的小伙伴也可以用该方法来写,对加深对该方法的理解度和速度都是有帮助的)
注意事项:
这题的题目范围是 1≤L≤1e8,1<=M<=1e6
差分数组开个1e8+5就可以了,开大数组的时候建议开到main外面,不然容易爆
同时要注意,这里有M次输入,而且M的值比较大,如果使用cin,cout来输入输出的话就会比较慢,加上差分数组求前缀和的时候要for循环,超时风险直线上升,所以得把cin换成scanf,不然就过不了(本人第一次就因为这个原因没过)
如果硬是想用cin,cout来输入输出的话,在main中加上std::ios::sync_with_stdio(false);就好了(至于怎么原因,在此就不多赘述了,大家可以搜索一下)
稍微拓展一下:
在main函数里面的数组是开在栈区(stack)的,而在函数外面的是开在数据区的。栈区的内存比较小,所以当数组非常大的时候,就会报错。而把数组放在数据区就不会出现这个问题,因为数据区的内存比较的大
- 栈区:由操作系统自动分配释放,存放函数的参数值,局部变量的值,当不需要式系统会自动清除。
- 堆区:由new分配的内存块,不由编译器管,由应用程序控制(相当于程序员控制)。如果程序员没有释放掉,程序结束后,操作系统会自动回收。
- 数据区:也称全局区或者静态区,存放全局的东西类似全局变量。
- 代码区:存放执行代码的地方,类似if else,while,for这种语句。
使用scanf和printf:
#include"bits/stdc++.h" using namespace std; int a[100000005]={0}; //数组开的空间很大建议放外面 int main() { int b,c,d,i,j,l,m,n; scanf("%d%d",&l,&m); a[0]=1; for(int i=0;i<m;i++) { scanf("%d%d",&b,&c); a[b]+=1; a[c+1]-=1; } int sum=0,summ=0; for(int i=0;i<=l;i++) { sum+=a[i]; if(sum==1) summ++; } printf("%d",summ); return 0; }
使用cin和cout:
#include"bits/stdc++.h" using namespace std; int a[100000005]={0}; int main() { //加上这条语句就可以使用cin和cout了 std::ios::sync_with_stdio(false); int b,c,d,i,j,l,m,n; cin>>l>>m; a[0]=1; for(int i=0;i<m;i++) { cin>>b>>c; a[b]+=1; a[c+1]-=1; } int sum=0,summ=0; for(int i=0;i<=l;i++) { sum+=a[i]; if(sum==1) summ++; } cout<<summ; return 0; }
<由于作者水平有限,文中若出现有错误的地方,还请大佬斧正>