前缀和 差分 刷题题解

文章介绍了如何使用前缀和和差分数组优化一维数组的区间计算,包括计算前缀和以及通过差分数组实现区间修改,以提高查询和修改操作的效率。
摘要由CSDN通过智能技术生成

1.一维数组的前缀和

   

思路:

利用前缀和的算法,定义出一个新的数组prefix去存储每个区间的和,方便查询的结果,复杂度为O(1),然后结合前缀和的性质,进行区间的计算,如下,

sum[1,k]+sum[k+1,n]=sum[1,n]

//相当于区间的加和,由上边的等式,就可以推算出求前缀和区间的公式

ans=P[r] - P[l-1]

题解代码如下:

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long 
const int N=1e5 + 10;
int a[N],prefix[N];
void solve()
{
   int n,q;
   cin>> n >> q;
   for(int i=1;i<=n; ++i)cin>>a[i];
   for(int i=1;i<=n ; ++i)prefix[i]=prefix[i-1]+a[i];
   while(q--)
   {
    int l,r;
    cin>> l >> r;
    cout<< prefix[r] - prefix[l-1]<<endl;
   }
}
signed main()
{
   ios::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);

   int t=1;
   cin>>t;
   while(t--)
   solve();
   return 0;
}

2.一维数组的差分数组

思路:

  对于题目的要求,我们可以利用差分数组来解决问题。

差分:对于一个数组a[],我们有一个数组diff[i]=a[i]-a[i-1],来存储,

同时可以进行后缀区间的修改,例如要对[l,r]区间进行修改,那么就是对 diff[l] 进行修改,这样会使得 a[l] 以后的所有数都参与了修改,这时候再对右端点修改 diff[r+1] 修改,就可以将 a[r+1] 之后的数组恢复原状,实现定位区间来修改的目的。下边是题解的代码

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long 
#define INF 0x3f3f3f3f
const int N=1e5 + 20;
// 开数组
int a[N],prefix[N],diff[N];
void solve()
{
   int n,p,q;
   cin>> n >> p >> q;
   for(int i=1 ; i<=n ; i++)cin>>a[i];
   for(int i=1 ; i <= n ; i++)diff[i]=a[i]-a[i-1];
   while(p--)
   {
    int 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];
   while(q--)
   {
    int l,r; cin>> l >> r ;
    cout<<prefix[r]-prefix[l-1]<<endl;
   }
}
signed main()
{
   ios::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);

   int t=1;
   while(t--)
   solve();
   return 0;
}

以上题集来自于starrycoding网站

01.前缀和与差分 | StarryCoding

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值