题目描述
小朋友排成一排,老师给他们分苹果。
小朋友从左到右标号1..N。有M个老师,每次第i个老师会给第Li个到第Ri个,一共Ri-Li+1个小朋友每人发Ci个苹果。
最后老师想知道每个小朋友有多少苹果。
数据规模和约定
100%的数据,N、M≤100 000,1≤Li≤Ri≤N,0≤Ci≤100。
输入
第一行两个整数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
这个题目用到了线段树的知识 因为用普通的循环 我们得到的时间复杂度为O(m*n) 肯定会超时
言归正传,所谓差分数组,就是说假设有两个数组d[i],a[i],d[i]=a[i]-a[i-1],d[0]=a[0],那么d[i]就是a[i]的差分数组,d[i]的前缀和就是a[i],即a[i]=d[i]+d[i-1]+...+d[0];
本题中,发苹果的方式是连续的,那么每次改变的差分数组只有d[l]和d[r+1],连续m次,
最后根据上述公式可以求出每个小朋友得到的苹果。
其实差分数组求和的原理就是数学上的裂项相消,可以说并不困难,可我就是没能想到,我能说什么呢!
# include <iostream>
# include <iomanip>
# include <algorithm>
using namespace std;
int main ()
{
int a,b;
cin>>a>>b;
int array[100001];
for(int g=0;g<100001;g++)
{
array[g]=0;
}
for(int g=0;g<b;g++)
{
int d,e,f;
cin>>d>>e>>f;
array[d]+=f;
array[e+1]-=f;
}
for(int c=1;c<=a;c++)
{
array[c]+=array[c-1];
}
for(int c=1;c<=a;c++)
{
cout<<array[c]<<" ";
}
cout<<endl;
}