mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
310 字
1 分钟
基础-前缀和与差分数组
2026-08-28

前缀和#

核心作用与缺陷#

  • 对于需要频繁求子数组范围求和的问题可以优化到o(1)
  • 但是数据不可以变更,否则前缀和数组变更的复杂度为o(n)
  • 因此,如果不需要用到原数组,可以不保存原数组

根据核心作用#

构建前缀和数组pre后#

  • 求某一区间和[L,R]:pre[R]-pre[L-1]
  • 求某个数R:pre[R+1]-pre[L]

#

未排序数组中累加和为给定值的最长子数组长度_牛客题霸_牛客网#

int n,m;
void solve(){
cin>>n>>m;
vector<ll>pre(n+1,0);
unordered_map<ll,int> hp;
hp[0]=0; // 解决前缀和刚好等于m的这个特殊情况,可以可以直接写特判
int ans=0;
for(int i=1;i<=n;i++){
cin>>pre[i];
pre[i]+=pre[i-1];
if(hp.find(pre[i])==hp.end()){
hp[pre[i]]=i;
}
if(pre[i]==m){
ans=max(ans,i);
}
else if(hp.find(pre[i]-m)!=hp.end()){
ans=max(ans,i-hp[pre[i]-m]);
}
}
cout<<ans;
}

560. 和为 K 的子数组#

int subarraySum(vector<int>& nums, int k) {
int n=nums.size();
vector<int> pre(n+1,0);
for(int i=1;i<=n;i++){
pre[i]=nums[i-1];
pre[i]+=pre[i-1];
}
unordered_map<ll,ll> hp;
ll ans=0;
hp[0]=1;
for(int i=1;i<=n;i++){
if(pre[i]==k){
ans+=hp[0];
}
if(hp.find(pre[i]-k)!=hp.end()){
ans+=hp[pre[i]-k];
}
hp[pre[i]]++;
}
return ans;
}

未排序数组中累加和为给定值的最长子数组系列问题补1#

int n;
void solve(){
cin>>n;
vector<int> pre(n+1,0);
unordered_map<int,int> hp;
int ans=0;
for(int i=1;i<=n;i++){
int x;cin>>x;
if(x>0){
pre[i]=1;
pre[i]+=pre[i-1];
}
else if(x<0){
pre[i]=-1;
pre[i]+=pre[i-1];
}
else{
pre[i]=x;
pre[i]+=pre[i-1];
}
if(pre[i]==0){
ans=max(ans,i);
}
else if(hp.find(pre[i])!=hp.end()){
ans=max(ans,i-hp[pre[i]]);
}
if(hp.find(pre[i])==hp.end()){
hp[pre[i]]=i;
}
}
cout<<ans;
}

1124. 表现良好的最长时间段#

按理来讲在找pre[i]<=0pre[i]<=0这种情况既要考虑找比pre[i]pre[i]小又要i最小,理论上要维护两个值,但是由于划归后整个前缀和数组的变化趋势是连续的且首项一定是0,因此当你要找比pre[i]1pre[i]-1还要小的值时,如果存在这个答案,那么一定还有一个pre[i]1pre[i]-1在这个答案前面,因为这个答案本身也是通过pre[i]1pre[i]-1和-1贡献计算出来的

int longestWPI(vector<int>& hours) {
int n=hours.size();
vector<int> pre(n+1,0);
unordered_map<int,int> hp;
int ans=0;
for(int i=1;i<=n;i++){
if(hours[i-1]>8){
pre[i]=1;
}
else{
pre[i]=-1;
}
pre[i]+=pre[i-1];
if(pre[i]>0){
ans=max(ans,i);
}
else{
if(hp.find(pre[i]-1)!=hp.end()){
ans=max(ans,i-hp[pre[i]-1]);
}
}
if(hp.find(pre[i])==hp.end()) hp[pre[i]]=i;
}
return ans;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

基础-前缀和与差分数组
https://blog.hydrodyio.xyz/posts/基础-前缀和与差分数组/
作者
Hydroiody
发布于
2026-08-28
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录