前綴和&差分


一:差分數組概念

 一、差分數組的定義及用途

1.定義:
對於已知有n個元素的數列d,建立記錄它每項與前一項差值的差分數組f:顯然,f[1]=d[1]-0=d[1];對於整數i∈[2,n],我們讓f[i]=d[i]-d[i-1]。//f[i]數組為差分數組,d[i]數組為原數組

2.簡單性質:
(1)計算數列各項的值:觀察d[2]=f[1]+f[2]=d[1]+d[2]-d[1]=d[2]可知,d[i]=f[i]的前綴和。
(2)計算數列每一項的前綴和:第i項的前綴和即為數列前i項的和,那么推導可知

//此處求的是d[i]數組的前綴和呼應3.(2)

即可用差分數組求出數列前綴和;

3.用途:
(1)快速處理區間加減操作:
對數列區間[L,R]中的每個數加上x,我們通過性質(1)知道,第一個受影響的差分數組中的元素為f[L],即令f[L]+=x,那么后面數列元素在計算過程中都會加上x;

最后一個受影響的差分數組中的元素為f[R],所以令f[R+1]-=x,即可保證不會影響到R以后數列元素的計算。

這樣我們不必對區間內每一個數進行處理,只需處理兩個差分后的數即可;

(2)詢問區間和問題:
由性質(2)我們可以計算出數列各項的前綴和數組sum各項的值;那么顯然,區間[L,R]的和即為ans=sum[R]-sum[L-1];

 

二:差分&前綴和模板題

#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const ll maxn=100010;
ll p[maxn],a[maxn],b[maxn],c[maxn],ans[maxn];
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;++i)
        cin>>p[i];
    for(ll i=1;i<n;++i)
        cin>>a[i]>>b[i]>>c[i];
    for(ll i=1;i<m;++i)
    {
        if(p[i]>p[i+1])
            ans[p[i+1]]++,ans[p[i]]--;
        else ans[p[i]]++,ans[p[i+1]]--;
    }
    for(ll i=1;i<=n;++i)
        ans[i]+=ans[i-1];
    ll sum=0;
    for(ll i=1;i<n;++i)
        sum+=min(a[i]*ans[i],c[i]+b[i]*ans[i]);
    cout<<sum<<endl;
    return 0;
}

 

差分與前綴和互逆,求完差分后可以求前綴和得到修改后的數據

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM