谁说前缀和不是dp(手动滑稽)
我们发现前i个数的和pre[i]就等于前i-1个数的和pre[i-1]加上第i个数a[i]
状态设计为pre[i],表示前i个数的前缀和
转移方程为pre[i] = pre[i-1]+a[i]
再考虑查询,我们发现要统计[l,r]区间内的数字之和,如果取pre[r]就多算了前l-1个数之和,而前l-1个数之和恰好就是pre[l-1],故查询的结果是pre[r]-pre[l-1]
实现:
C++可以用std::partial_sum计算前缀和,该函数在<numeric>头文件中,C++20开始支持
正好最近也在学习Python,贴一份C++代码,再贴一份Python代码
#include <iostream>
#include <vector>
#include <numeric>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n,q;
std::cin >> n >> q;
std::vector<i64> a(n+1);
for(int i = 1; i <= n; i++){
std::cin >> a[i];
}
std::vector<i64> pre(n+1);
std::partial_sum(a.begin(),a.end(),pre.begin());
auto query = [&](int l,int r){
return pre[r]-pre[l-1];
};
for(int i = 0; i < q; i++){
int l,r;
std::cin >> l >> r;
std::cout << query(l,r) << "\n";
}
}
import sys
input = lambda: sys.stdin.readline().strip()
n,q = map(int,input().split())
a = list(map(int,input().split()))
a = [0]+a
pre = [0]*(n+1)
for i in range(1,n+1):
pre[i] = pre[i-1]+a[i]
res = []
for i in range(q):
l,r = map(int,input().split())
res.append(pre[r]-pre[l-1])
print("\n".join(map(str,res)))

京公网安备 11010502036488号