前缀和
1. 这是什么东东
它是一种算法,可以将O(n)的速度转换成O(1)的速度,快速求出区间和与区间乘积。
2. 如何实现
举个例子洛谷P8218这道区间求和的题。
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[100005],sum[100005],l,r;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];//sum[i]为区间[1,i]的和,不停的叠加。
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>l>>r;//输入区间。
cout<<sum[r]-sum[l-1]<<'\n';//输出区间和。
}
}
定义:sum[r]-sum[l-1]为区间[l,r]的和。
差分
1. 这又是什么东东
它也是一种算法,可以将n次O(n)的区间加与区间减操作变成n次O(1)的加法运算加一次前缀和。
2. 如何实现
以下是区间加的代码。
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[100005],add[100005],sum,l,r,x;
int main(){
cin>>n;//输入数组的长度。
for(int i=1;i<=n;i++)cin>>a[i];//输入数组的每一个数。
cin>>m;//输入要进行区间加的次数。
for(int i=1;i<=m;i++){
cin>>l>>r>>x;//输入要进行加法运算的区间,与要加的数。
add[l]+=x;
add[r+1]-=x;
}
for(int i=1;i<=n;i++){
add[i]+=add[i-1];//设add[i]为add数组[1,i]的和。
//add[i]现在为数组第i个数要加的数。
a[i]+=add[i];
}
for(int i=1;i<=n;i++)cout<<a[i]<<' ';//输出数组的每一个数。
}
定义:差分数组进行前缀和后为我们想要的数组。