算法提高 分蘋果
小朋友排成一排,老師給他們分蘋果。
小朋友從左到右標號1…N。有M個老師,每次第i個老師會給第Li個到第Ri個,一共Ri-Li+1個小朋友每人發Ci個蘋果。
最後老師想知道每個小朋友有多少蘋果。
輸入格式:
第一行兩個整數N、M,表示小朋友個數和老師個數。
接下來M行,每行三個整數Li、Ri、Ci,意義如題目表述。
輸出格式:
一行N個數,第i個數表示第i個小朋友手上的水果。
輸入樣例:
在這裏給出一組輸入。例如:
5 3
1 2 1
2 3 2
2 5 3
輸出樣例:
在這裏給出相應的輸出。例如:
1 6 5 3 3
數據規模和約定
40%的數據,N、M≤1 000。
100%的數據,N、M≤100 000,1≤Li≤Ri≤N,0≤Ci≤100。
思路:
這道題題意十分的簡單,就是對數組區間R~L加上C,用常規的循環做加法算出結果是沒問題的,但肯定會超時。這道題可以用差分數組來做。下面簡單介紹一下差分數組。
1.定義:
對於已知有n個元素的離線數列d,我們可以建立記錄它每項與前一項差值的差分數組f:顯然,f[1]=d[1]-0=d[1];對於整數i∈[2,n],我們讓f[i]=d[i]-d[i-1]。
2.簡單性質:
(1)計算數列各項的值:觀察d[2]=f[1]+f[2]=d[1]+d[2]-d[1]=d[2]可知,數列第i項的值是可以用差分數組的前i項的和計算的,即d[i]=f[i]的前綴和。
(2)計算數列每一項的前綴和:第i項的前綴和即爲數列前i項的和,那麼推導可知
即可用差分數組求出數列前綴和;
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];
這道題就是用於區間加減,時間複雜度只有O(1)。
參考文章: https://www.cnblogs.com/COLIN-LIGHTNING/p/8436624.html
代碼:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int M, N, R, L, C;
cin >> N>>M;
vector<int>children(N+2);
for (int i = 0; i < M; i++)
{
cin >> R >> L >> C;
children[R] += C;
children[L + 1] -= C;
}
for (int i = 1; i <= N; i++)
{
children[i] += children[i - 1];
cout << children[i] << ' ';
}
return 0;
}