差分数组:理解

差分数组:

差分数组的思路其实是通过差分,递推出经过部分区间修改后的原数组,例如我们要对区间进行加减操作,最终求某个区间的值

举个栗子:

a[ ] 1 2 3 4 5
差分p[ ] 1 1 1 1 1

修改区间:

| [1 5] +2 | [2,3] -1| [1 3] +3 |
修改后的差分p[ ] 6 0 1 -1 1
修改后的a[ ] 6 6 7 6 7

讲解:

我们只需要让差分数组p[l]+=w p[r+1]-=w 我们可以通过最初的差分p[1]得到修改后的a[],只需要通过递推式即可得到,由于p[1]的差分是其本身我们就可以利用递推式得到修改后的原数组。递推式:p[i]+=p[i-1]

例题推荐:区间

题解:

利用差分或者树状数组,两个树状树状比较快而且性能比较优,但是差分也可以,是种思想需要理解

AC代码:

#include<bits/stdc++.h>
using namespace std;
//差分数组
//区间和
#define ll long long
const  int maxn=1000001;
ll a[maxn],p[maxn];
int main()
{
    ll n,q;
    //cout<<maxn;
    scanf("%lld %lld",&n,&q);
    for(ll i=1; i<=n; i++)
    {
        scanf("%lld",&a[i]);
        p[i]=a[i]-a[i-1];
    }
    while(q--)
    {
        ll l,r,op,w;
        scanf("%lld",&op);
        if(op==1)
        {
            scanf("%lld %lld %lld",&l,&r,&w);
            p[l]-=w;
            p[r+1]+=w;
        }
        else
        {
            scanf("%lld %lld %lld",&l,&r,&w);
            p[l]+=w;
            p[r+1]-=w;
        }
    }
    for(ll i=1;i<=n;i++)
    {
        p[i]=p[i]+p[i-1];
        a[i]=a[i-1]+p[i];
    }
    ll l,r;
    scanf("%lld %lld",&l,&r);
    printf("%lld\n",a[r]-a[l-1]);

}
发布了205 篇原创文章 · 获赞 12 · 访问量 8497

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/103961471
今日推荐