东华大学oj分苹果 (差分数组方法)

分苹果

时间限制: 1s

类别: 一维数组->较难

问题描述

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

输入说明

  第一行两个整数N、M,表示小朋友个数和老师个数。
  接下来M行,每行三个整数Li、Ri、Ci,意义如题目表述。

      N、M≤100 000,1≤Li≤Ri≤N,0≤Ci≤100。

输出说明

  一行N个数,第i个数表示第i个小朋友手上的水果。

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int n, m;
	cin >> n >> m;
	vector<int>diff(n + 1, 0);
	//动态数组初始化 
	vector<int>apples(n + 1, 0);
	int a, b, c;
	for (int i = 0; i < m; i++)
	{
		cin >> a >> b >> c;
		if (c == 0)continue;
		diff[a] += c;
		if (b + 1 <= n)
		{
			diff[b + 1] -= c;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		apples[i] = apples[i - 1] + diff[i];
		cout << apples[i] << ' ';
	}
	return 0;
}

哦吼吼 你是不是以为这题很简单 然后发现tle了 

哈哈 其实是算法的问题

很明显 那个案例是很多数据的 所以算法很重要

接下来 我向大家 介绍一种 算法 (差分数组)

这种算法 应对的是 对于 一个数组的 一个区间 同时加或减去某个数

这道例题就很经典了

差分数组 什么意思呢

比如 5个同学 

此时 apples 0 0 0 0 0 0 (这里多开了一个数)

diff(表示的是 当前位置的apples个数 - 前一个位置的apples 个数)

也是 0 0 0 0 0 0 (同样多开一个数)

哎 这时候 说了  把第一个同学 到第 3个都加一

我们来调整差分数组

根据上面的定义可知

此时 diff 0 0 0 0 0 0 变成 diff 0 1(第一个数-第0个) 0(第2个-第一个) 0 -1(第4个-第3个) 0

于是通过模拟 我们可以知道 需要  diff[a]+=c ,diff[b+1]-=c;滴滴 这里需要判断一下

因为d可能是第n个人 那么d+1越界了

所以当d+1<=n的时候 diff[d+1]-=c;

这种操作 你发现 时间复杂度 变成 O(m)

不是O(m*平均区间长度)

(仅指加减操作的位置

然后就是打印 

上面diff的定义可知

apples[i] = diff[i]+apples[i-1];

这里就给出了为神马 我们要在前面多弄一个0   不然 i从 0开始 -1又溢出了

为了不溢出 就得把第一项单独来看 即diff[1] =apples[1];

后面再按照公式来打印

如果有哪里有疑问可以评论 共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值