前缀和算法
其实也不算算法,是一种做题技巧,通过使用记录1到n的总和,使用公式来,得出任意区间的和
假设 有一个数组 a[1]......a[n];
记录他们的每个数1到i的总和 s[i] = s[i-1] + a[i];
公式: i 到 j 的和为 ans = s[j] - s[i - 1]
代码
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int a[N], s[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];//注意从1开始计数
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
while(m--){
int l,r;
cin>>l>>r;
cout<<(s[r]-s[l-1])<<endl;
}
return 0;
}
差分
差分和前缀和差不多,但他可以随意增加一段 l 到 r 的数值,最后可以得到每个数组的数值
假设 数组 a[1].....a[n]
差分数组 b[i] = a[i] - a[i - 1]
在任意区间加上数值为 b[l] += i, b[r + 1] -= i;
最终得到累加起来就是总数
代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int s[N], b[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>s[i];//存放原数组
// for(int i=1;i<=n;i++) cout<<s[i]<<' ';
// cout<<endl;
for(int i=1;i<=n;i++) b[i] = s[i]-s[i-1];//构造差分数组
while(m--){
int l,r,c;
cin>>l>>r>>c;
b[l]+=c;//将l和以后加c
b[r+1]-=c;//将r之后-c
}
for(int i=1;i<=n;i++){
b[i]=b[i-1]+b[i];//将差分改为原数组
cout<<b[i]<<' ';
}
return 0;
}