求子区间面积和

153 篇文章

已下架不支持订阅

题目解析

本题的原型题应该是:区区区间间间,题目解析可以参考:区区区间间间_牛客博客

大家可以先看懂牛客这道题,然后再来看本题。

本题需要我们求解出:给定数组的所有子区间的面积之和

子区间面积 =(子区间内最大值 - 子区间内最小值)* 子区间长度

数组长度 N 最大是 10^5,因此只要是枚举所有子区间,那么肯定会超时。

子区间面积公式,可以变形如下:

子区间面积 =子区间内最大值 * 子区间长度 - 子区间内最小值 * 子区间长度

那么所有子区间面积之和,其实可以分解为下面两部分的差:

  • 子区间1内最大值

已下架不支持订阅

二维树状数组,也称为段树或区间树,是一种数据结构,常用于处理区间查询更新的问题,特别是求解区间内元素的、最大值、最小值等统计信息。在你的问题中,你需要计算给定子区间有多少个数与某个特定数值不同。 要解决这个问题,你可以按照以下步骤构建树状数组: 1. **初始化**:对于每个节点i,存储区间(通常是原数组中的元素之),初始时,所有节点的为对应位置的原始值。 2. **更新操作**:如果需要改变某个区间内的值,首先更新这个区间在树中的表示,然后根据二分查找的原则,向上递归更新父节点,直到根节点。 3. **查询操作**:对于求子区间有多少个数与指定值不同,可以通过计算两个连续区间(当前区间包含指定值的区间)的差来得到答案。例如,如果`arr[l..r]`是待查询区间,而`val`是你指定的数值,那么答案就是`(sum(r) - sum(l - 1)) - (count(arr, l, r, val) * val)`。这里`sum(i)`是第i个节点的,`count(arr, i, j, val)`是区间[i, j]中有多少个等于`val`的数。 4. **计数查询**:`count(arr, i, j, val)`可以用两个指针从两端开始遍历,每次比较当前位置的值是否与`val`相等,如果不相等则增加计数器。 为了实现这样的功能,你需要定义一些辅助函数,如`update`, `sum`, `count`。以下是一个简单的C++代码片段,假设`arr`是原始数组,`n`是数组长度,`val`是你要查找的值: ```cpp int tree[4 * n]; // 树状数组 void update(int idx, int val) { for (idx += n; idx > 0; idx >>= 1) tree[idx] = arr[idx] + tree[idx]; } int query_sum(int l, int r) { int sum = 0; for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l & 1) sum += tree[l++]; if (r & 1) sum += tree[--r]; } return sum; } int count(const vector<int>& arr, int i, int j, int val) { int count_left = 0, count_right = 0; for (i++; i <= j; i++) { if (arr[i] != val) count_left++; } for (j--; j >= i; j--) { if (arr[j] != val) count_right++; } return count_left + count_right; } ``` 现在你可以使用`update`来设置区间值,`query_sum`来获取子区间,然后用`count`来计算不同数的数量了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员阿甘

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

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

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

打赏作者

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

抵扣说明:

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

余额充值