算法提高 分蘋果

算法提高 分蘋果

小朋友排成一排,老師給他們分蘋果。
小朋友從左到右標號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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章