输入一个长度为 nn 的整数序列。
接下来再输入 mm 个询问,每个询问输入一对 l,rl,r。
对于每个询问,输出原序列中从第 ll 个数到第 rr 个数的和。
输入格式
第一行包含两个整数 nn 和 mm。
第二行包含 nn 个整数,表示整数数列。
接下来 mm 行,每行包含两个整数 ll 和 rr,表示一个询问的区间范围。
输出格式
共 mm 行,每行输出一个询问的结果。
数据范围
1≤l≤r≤n1≤l≤r≤n,
1≤n,m≤1000001≤n,m≤100000,
−1000≤数列中元素的值≤1000−1000≤数列中元素的值≤1000
输入样例:
5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10
给出差分模板代码:
#include<iostream>
using namespace std;
int const N=1e5+10;
int a[N],b[N];
void insert(int l,int r,int c)
{
b[l]+=c;
b[r+1]-=c;
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)scanf("%d",&a[i]);
for(int i=1; i<=n; i++)insert(i,i,a[i]);
while(m--)
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
insert(l,r,c);
}
for(int i=1; i<=n; i++)b[i]+=b[i-1];
for(int i=1; i<=n; i++)printf("%d ",b[i]);
return 0;
}
思路:
差分即 通过
b[1]=a[1]
b[2]=a[2]-a[1]
b[3]=a[3]-a[2]
.
.
.
b[n]=a[n]-a[n-1];
则此时 a[i]数组的任意一项即为 b[i]的前缀和,例如 a[3]=b[3]+b[2]+b[1]=a[3]-a[2]+a[2]-a[1]+a[1];
那么此时即可通过求 b的前缀和实现对 a[i]数组进行插入操作;
第一步构造一个b[i]数组 实现 b[i]=a[i]-a[i-1];
代码实现为:
void insert(int l,int r,int c)
{
b[l]+=c;
b[r+1]-=c;
}
for(int i=1; i<=n; i++)insert(i,i,a[i]);
例如:前提定义全局数组时 自动将所有数组的元素初始化为0
当i=1 b[1]=b[1]+a[1]=0+a[1]=a[1];
b[2]=b[2]-a[1]=-a[1]=0-a[1]=-a[1];
当i=2
b[2]=b[2]+a[2]=a[2]-a[1];(此时经过第一步的处理后b[2]!=0 而b[2]=-a[1]);
b[3]=b[3]-a[2]=-a[2];
.
.
.
当i=n时
b[n]=b[n]+a[n]=a[n]-a[n-1];
b[n+1]=b[n+1]-a[n]=-a[n];
从而实现 b[n=a[n]-a[n-1];
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复