前缀和
问题描述
给定一个长度为n的数组a,有q次询问,每次询问数组a在区间[l,r]的和。
输入格式
第一行一个整数n,(1<=n<=e5)
第二行n个整数表示数组a。(-e9<=ai<=e9)
第三行一个整数q。(1<=q<=e5)
接下来q行,每行两个整数li,ri(1<=li<=ri<=n)
输出格式
每一行对应每一个样例,输出一个整数表示答案
样例输入
5
1 2 3 4 5
2
1 3
2 5
样例输出
6
14
题解:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll n = 1e5 + 9;
ll a[n];
ll prefix[n];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
prefix[i] = prefix[i - 1] + a[i];
}
ll q;
cin >> q;
while (q--) {
ll l, r;
cin >> l >> r;
cout << prefix[r] - prefix[l - 1] << endl;;
}
return 0;
}
总结:
①首先输入n表示原始数组中的元素个数。通过for循环遍历数组使原始数组初始化。
②预处理一个前缀和数组prefix[n]。
③程序读取查询次数q,并执行q次查询。每次查询读取两个整数l和r,并输出数组a中区间[l, r]的和,即prefix[r] - prefix[l-1]。
差分
问题描述
给定一个长度为n的数组a,进行m次修改,有q次询问,每次询问数组a在区间[l,r]的和。
输入格式
第一行一个整数n,(1<=n<=e5)
第二行n个整数表示数组a。(-e9<=ai<=e9)
第三行一个整数m。(1<=m<=e5)
接下来m行,每行两个整数li,ri,xi。(1<=li<=ri<=n,-e9<=x<=e9)
接下来一行一个整数q。(1<=q<=e5)
接下来q行,每行两个整数li,ri。(1<=li<=ri<=n)
输出格式
对于每一次询问,输出一个整数表示答案。
样例输入
5
1 1 1 1 1
2
1 3 1
2 5 -2
2
1 2
3 4
样例输出
2
-1
题解:
#include <bits/stdc++.h>
using namespace std;
using ll = long long ;
const ll n = 1e5 + 9;
ll a[n], prefix[n], diff[n];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
diff[i] = a[i] - a[i - 1];
}
ll m;
cin >> m;
while (m--) {
ll l, r, x;
cin >> l >> r >> x;
diff[l] += x;
diff[r + 1] -= x;
}
for (int i = 1; i <= n; i++) {
a[i] = a[i - 1] + diff[i];
}
for (int i = 1; i <= n; i++) {
prefix[i] = prefix[i - 1] + a[i];
}
ll q;
cin >> q;
while (q--) {
ll l, r;
cin >> l >> r;
cout << prefix[r] - prefix[l - 1] << endl;
}
return 0;
}
总结:
①首先输入n,表示原始数组中有n个元素。遍历原始数组使其初始化。
②定义一个差分数组表示相邻两个元素之间的差值。通过遍历给差分数组赋值。
③然后对差分数组进行m次修改。diff[l]+=x;diff[r+1]-=x;经这两部操作,对目标区间完成了修改操作。
④随后通过差分数组,对原始数组进行更新。a[i]=a[i-1]+diff[i];
⑤最后,对更新后的数组求前缀和。即prefix[i]=prefix[i-1]+a[i];