您的位置:首页 > 其它

20200314之分苹果 (前缀和差分)

2020-04-07 12:22 1486 查看

题目描述
小朋友排成一排,老师给他们分苹果。
小朋友从左到右标号1…N。有M个老师,每次第i个老师会给第Li个到第Ri个,一共Ri-Li+1个小朋友每人发Ci个苹果。
最后老师想知道每个小朋友有多少苹果。

数据规模和约定
100%的数据,N、M≤100000,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

好吧 先补知识吧
如果不用前缀和,暴力的时间复杂度是M*(Ri-Li+1),也即MN,可以写,非常流畅的写出来发现TLE。
(内心os:我真的很想吐槽这个TLE,是整个思路方法的错误,那还不是结果错误,是思想就不对要重新思考找简便方法,这个真让人挠头!)
于是前缀和, 复杂度M(O(1))=O(M)
d[i]表示从1~i数组元素的和,对于区间l-r的元素之和d=d[r]-d[l-1],求出这个区间里的元素和。
二维前缀和
在O(1)时间复杂度求出元素和 矩阵(x1,y1)(x2,y2)由对角点确定 d(x2,y2)-d(x1,y1-1)-d(x1-1,y1)-d(x1-1,y1-1)
但是!我们清晰的看到分苹果它要求的是区间里每个小朋友手里的苹果数!OK用差分
差分 这次数组d[i]=a[i]-a[i-1],所以a[i]=d[1]+d[2]+…+d[i]!我们想用d数组算出a数组的值。可以试想,在[l,r]区间加或减一个数字,只有d[l]和d[r+1]的值发生了变化。所以!!!每次我都只改d[l]和d[r+1]即可!d[l]+=k,d[r+1]-=k,最后输出按上面公式求出a[i]即可

言归正传分苹果代码
学完了看学长代码很明白就看懂了
一开始小朋友手里都没有苹果 所以a数组都为0不写也可
全局数组相当于赋0,局部是随机值,有赋值后其他变0
另外 学长这个格式控制写的也太优秀了吧!真的是 非常秀!

#include <bits/stdc++.h>
using namespace std;
const int n=1e5+10;
int d[n];
int main(){
int N,M;
cin>>N>>M;
while(M--){
int l,r,c;
cin>>l>>r>>c;
d[l]+=c;
d[r+1]-=c;
}
int sum=0;
for(int i=1;i<=N;i++){
sum+=d[i];
printf("%d%c",sum,i==n?'\n':' ');
}
return 0;
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
是IMI呀 发布了38 篇原创文章 · 获赞 0 · 访问量 707 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: