大学里到树木要打药(蓝桥杯)

大学里到树木要打药

题目描述

教室外有 N 棵树(树的编号从 0∼N−1),根据不同的位置和树种,学校要对其上不同的药。

因为树的排列成线性,且非常长,我们可以将它们看作一条直线给他们编号。

对于树的药是成区间分布,比如 3∼5 号的树靠近下水道,所以他们要用驱蚊虫的药,20∼26 号的树,他们排水不好,容易涝所以要给他们用点促进根系的药 ⋯诸如此类。

每种不同的药要花不同的钱。

现在已知共有 M 个这样的区间,并且给你每个区间花的钱,问最后这些树木要花多少药费。

输入描述
每组输入的第一行有两个整数 N和 M。N 代表马路的共计多少棵树,M 代表区间的数目,N 和 M 之间用一个空格隔开。

接下来的 M 行每行包含三个不同的整数,用一个空格隔开,分别表示一个区域的起始点 L 和终止点 R 的坐标,以及花费。

1≤L≤R≤N≤106 ,1≤M≤105,保证花费总和不超过 int 范围。

输出描述
输出包括一行,这一行只包含一个整数,所有的花费。

输入输出样例
示例

输入

500 3
150 300 4
100 200 20
470 471 19

输出

2662

差分

#include<bits/stdc++.h> // 包含大部分标准库
using namespace std;

const int z = 1000010; // 设置数组的最大长度,因为数据范围是1≤L≤R≤N≤10^6^,1≤M≤10^5^
int a[z], b[z]; // a是用来存储每个位置的总花费的数组,b是差分数组

int main()
{
    int n, m; // n代表树木的总数,m代表区间的数目
    int sum = 0; // 初始化总花费
    scanf("%d %d", &n, &m); // 读入n和m
    while(m--)
    {
        int l, r, c; // l代表区间的起始点,r代表区间的终止点,c代表区间的花费
        scanf("%d %d %d", &l, &r, &c); // 读入区间信息
        b[l] += c; // 在左端点累加花费c
        b[r + 1] -= c; // 在右端点的下一个位置减去花费c
    }
    for(int i = 1; i <= n; i++)
    {
        a[i] = a[i - 1] + b[i]; // 计算每个位置的累计花费
        sum += a[i]; // 累加总花费
    }
    printf("%d", sum); // 输出总花费
    return 0;
}

这段代码的核心思想是差分数组。差分数组是一种特殊的数组,它记录了元素与前一个元素之差的变化。在本题中,我们可以将树木的位置看作一条直线,使用差分数组来记录每个位置的累计花费。

首先,读入树木的总数n和区间的数目m。然后,对每个区间进行处理。对于每个区间,我们在区间的起始点累加花费c,而在区间的终止点的下一个位置减去花费c。这样,差分数组b中的每个元素表示该位置的花费变化量。

接下来,我们通过计算差分数组b的前缀和得到每个位置的累计花费。每个位置的累计花费等于前一个位置的累计花费加上该位置的花费变化量。同时,我们也累加每个位置的花费到总花费sum中。

最后,输出总花费sum。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

命运从未公平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值