小朋友排成一排,老师给他们分苹果。
小朋友从左到右标号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
线段树做法:
//这里分苹果是区间修改,且数据量比较大,因此使用线段树来解决
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100002;
int sum[maxn<<2],Lazy[maxn<<2]; //线段树一般要开辟4倍于数据量的存储空间,区间求和需要懒惰标记lazy
int n,m;
void Pushup(int k) //上推函数更新结点
{
sum[k] = sum[k*2]+sum[k*2+1];
}
void Pushdown(int rt,int ln,int rn) //下推函数
{
if(Lazy[rt])
{
Lazy[rt*2]+=Lazy[rt];
Lazy[rt*2+1]+=Lazy[rt];
sum[rt*2]+=Lazy[rt]*ln;
sum[rt*2+1]+=Lazy[rt]*rn;
Lazy[rt] = 0;
}
}
void Updata(int L,int R,int C,int left,int right,int rt)//区间修改
{
if(L<=left&&right<=R)
{
sum[rt]+=C*(right-left+1);
Lazy[rt]+=C;
return ;
}
int m = (left+right)>>1;
Pushdown(rt,m-left+1,right-m); //下推
if(L<=m) Updata(L,R,C,left,m,rt<<1);
if(R>m) Updata(L,R,C,m+1,right,(rt<<1)+1);
Pushup(rt); //上推更新节点
}
//区间查询
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return sum[rt];
}
int m = (l+r)>>1;
Pushdown(rt,m-l+1,r-m);
int ans = 0;
if(L<=m) ans+=Query(L,R,l,m,rt<<1);
if(R>m) ans+=Query(L,R,m+1,r,(rt<<1)+1);
return ans;
}
int main()
{
cin>>n>>m;
int l,r,c;
memset(sum,0,sizeof(sum));
memset(Lazy,0,sizeof(Lazy));
for(int i =1;i<=m;i++)
{
cin>>l>>r>>c;
Updata(l,r,c,1,n,1);
}
for(int i = 1;i<=n;i++)
{
printf("%d ",Query(i,i,1,n,1));
}
cout<<endl;
return 0;
}
树状数组做法:
#include "iostream"
#include "cstring"
#include "algorithm"
using namespace std;
//typedef long long ll;
//const int INF = 1e9;
const int maxn = 100010;
int A[maxn];
int n, m;
int lowbit(int x) {
return x & -x;
}
void update(int x, int k) {
while(x <= n) {
A[x] += k;
x += lowbit(x);
}
}
int query(int x) {
int res = 0;
while(x) {
res += A[x];
x -= lowbit(x);
}
return res;
}
int main() {
cin >> n >> m;
for(int i = 0; i < m; ++i) {
int l, r, k;
cin >> l >> r >> k;
update(l, k); //这里为核心代,本质上是区间修改
update(r + 1, -k);
}
for(int i = 1; i <= n; ++i) cout << query(i) << " ";
cout << endl;
return 0;
}