- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在从一个数据数组中实现线段树,我还想在更新一系列数据时保持树的最大/最小值。这是我遵循本教程的初步方法 http://p--np.blogspot.com/2011/07/segment-tree.html .不幸的是它根本不起作用,逻辑对我来说很有意义,但我对 b
和 e
有点困惑,我想知道这是数据
数组?或者它是树的实际范围?据我了解,max_segment_tree[1]
应该包含 [1, MAX_RANGE]
范围内的 max
而 min_segment_tree[1 ]
应该包含范围 [1, MAX_RANGE]
的 min
。
int data[MAX_RANGE];
int max_segment_tree[3 * MAX_RANGE + 1];
int min_segment_tree[3 * MAX_RANGE + 1];
void build_tree(int position, int left, int right) {
if (left > right) {
return;
}
else if (left == right) {
max_segment_tree[position] = data[left];
min_segment_tree[position] = data[left];
return;
}
int middle = (left + right) / 2;
build_tree(position * 2, left, middle);
build_tree(position * 2 + 1, middle + 1, right);
max_segment_tree[position] = max(max_segment_tree[position * 2], max_segment_tree[position * 2 + 1]);
min_segment_tree[position] = min(min_segment_tree[position * 2], min_segment_tree[position * 2 + 1]);
}
void update_tree(int position, int b, int e, int i, int j, int value) {
if (b > e || b > j || e < i) {
return;
}
if (i <= b && j >= e) {
max_segment_tree[position] += value;
min_segment_tree[position] += value;
return;
}
update_tree(position * 2 , b , (b + e) / 2 , i, j, value);
update_tree(position * 2 + 1 , (b + e) / 2 + 1 , e , i, j, value);
max_segment_tree[position] = max(max_segment_tree[position * 2], max_segment_tree[position * 2 + 1]);
min_segment_tree[position] = min(min_segment_tree[position * 2], min_segment_tree[position * 2 + 1]);
}
编辑添加测试用例:
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <deque>
#include <queue>
#include <fstream>
#include <functional>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
using namespace std;
const int MAX_RANGE = 20;
int data[MAX_RANGE];
int max_segment_tree[2 * MAX_RANGE];
int min_segment_tree[2 * MAX_RANGE];
int added_to_interval[2 * MAX_RANGE] = {0};
void update_bruteforce(int x, int y, int z, int &smallest, int &largest) {
for (int i = x - 1; i < y; ++i) {
data[i] += z;
}
// update min/max
smallest = data[0];
largest = data[0];
for (int i = 0; i < MAX_RANGE; ++i) {
if (data[i] < smallest) {
smallest = data[i];
}
if (data[i] > largest) {
largest = data[i];
}
}
}
void build_tree(int position, int left, int right) {
if (left > right) {
return;
}
else if (left == right) {
max_segment_tree[position] = data[left];
min_segment_tree[position] = data[left];
return;
}
int middle = (left + right) / 2;
build_tree(position * 2, left, middle);
build_tree(position * 2 + 1, middle + 1, right);
max_segment_tree[position] = max(max_segment_tree[position * 2], max_segment_tree[position * 2 + 1]);
min_segment_tree[position] = min(min_segment_tree[position * 2], min_segment_tree[position * 2 + 1]);
}
void update_tree(int position, int b, int e, int i, int j, int value) {
if (b > e || b > j || e < i) {
return;
}
if (i <= b && e <= j) {
max_segment_tree[position] += value;
min_segment_tree[position] += value;
added_to_interval[position] += value;
return;
}
update_tree(position * 2 , b , (b + e) / 2 , i, j, value);
update_tree(position * 2 + 1 , (b + e) / 2 + 1 , e , i, j, value);
max_segment_tree[position] = max(max_segment_tree[position * 2], max_segment_tree[position * 2 + 1]) + added_to_interval[position];
min_segment_tree[position] = min(min_segment_tree[position * 2], min_segment_tree[position * 2 + 1]) + added_to_interval[position];
}
void update(int x, int y, int value) {
// memset(added_to_interval, 0, sizeof(added_to_interval));
update_tree(1, 0, MAX_RANGE - 1, x - 1, y - 1, value);
}
namespace unit_test {
void test_show_data() {
for (int i = 0; i < MAX_RANGE; ++i) {
cout << data[i] << ", ";
}
cout << endl << endl;
}
void test_brute_force_and_segment_tree() {
// arrange
int number_of_operations = 100;
for (int i = 0; i < MAX_RANGE; ++i) {
data[i] = i + 1;
}
build_tree(1, 0, MAX_RANGE - 1);
// act
int operation;
int x;
int y;
int z;
int smallest = 1;
int largest = MAX_RANGE;
// assert
while (number_of_operations--) {
operation = rand() % 1;
x = 1 + rand() % MAX_RANGE;
y = x + (rand() % (MAX_RANGE - x + 1));
z = 1 + rand() % MAX_RANGE;
if (operation == 0) {
z *= 1;
}
else {
z *= -1;
}
cout << "left, right, value: " << x - 1 << ", " << y - 1 << ", " << z << endl;
update_bruteforce(x, y, z, smallest, largest);
update(x, y, z);
test_show_data();
cout << "correct:\n";
cout << "\tsmallest = " << smallest << endl;
cout << "\tlargest = " << largest << endl;
cout << "possibly correct:\n";
cout << "\tsmallest = " << min_segment_tree[1] << endl;
cout << "\tlargest = " << max_segment_tree[1] << endl;
cout << "\n--------------------------------------------------------------\n";
cin.get();
}
}
}
int main() {
unit_test::test_brute_force_and_segment_tree();
}
最佳答案
您需要单独存储每个间隔的最大值/最小值,以及添加到其中的值(只是它们的总和)。这是它可能出错的原因:
假设我们正在为数组 [5, 1, 3, 7] 构建一棵树(我将在这里只显示最小树)。这棵树看起来像这样:
1
1 3
5 1 3 7
然后我们将整个区间加 1。这棵树看起来像这样:
2
1 3
5 1 3 7
因为更新间隔完全覆盖第一个节点后,传播已停止。
然后在 [0-1] 范围内加 1。这个范围没有覆盖第一个节点的整个区间,所以我们更新 child ,然后将整个区间的最小值(即第一个节点的值)设置为节点2和3的最小值。这里是结果树:
2
2 3
5 1 3 7
这就是它出错的地方——数组中没有元素 2,但树声称整个数组的最小值是 2。发生这种情况是因为树的较低层从未真正获得信息它们的值已经增加 - 第二个节点不知道它的值不是 [5, 1] 而是 [6, 2] 这一事实。
为了使其正常工作,您可以添加第三个数组来保存已添加到整个间隔的值 - 例如,int added_to_interval[3 * MAX_RANGE + 1];
.然后,当您更新整个间隔时( i <= b && j >= e
的情况),您还必须增加 added_to_interval[position]
与 value
.此外,当沿着树向上更新子节点的值时,您还必须添加已添加到整个间隔的值(例如 max_segment_tree[position] = max(max_segment_tree[position * 2], max_segment_tree[position * 2 + 1]) + added_to_interval[position];
)。
编辑:
以下是为使其正常工作而对代码所做的更改:
if (i <= b && j >= e) {
max_segment_tree[position] += value;
min_segment_tree[position] += value;
added_to_interval[position] += value;
return;
}
...
update_tree(position * 2 , b , (b + e) / 2 , i, j, value);
update_tree(position * 2 + 1 , (b + e) / 2 + 1 , e , i, j, value);
max_segment_tree[position] = max(max_segment_tree[position * 2], max_segment_tree[position * 2 + 1]) + added_to_interval[position];
min_segment_tree[position] = min(min_segment_tree[position * 2], min_segment_tree[position * 2 + 1]) + added_to_interval[position];
我还没有对其进行广泛的测试 - 我将把它留给你,但我尝试了一堆似乎可以正常工作的示例。
此外,我认为数组中不需要 3 * MAX_RANGE + 1 个元素 - 2 * MAX_RANGE 或类似的元素就足够了。
关于c++ - 如何在保持最大值和最小值的同时更新线段树中的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11814425/
我在使用 Android 时遇到了一点问题。 我有我的 GPS 位置,明确的经纬度,以及以米为单位的搜索射线(例如 100 米),可以吗? 想象一下我在射线形成的圆心的位置,我会知道如何在 Andro
深夜的编程之旅 这是一个深夜,街头灯光昏暗,大部分人都已陷入梦乡。但对于我来说,这却是一个灵感迸发的时刻。窗外的星空仿佛在诉说着某种宇宙的密码,而键盘下的代码则是我解密这个宇宙的工具。 一个突如其来的
我将数据集结构定义为 struct Dataset: Hashable { var x: Double var y: Double } 然后是数组 var dataset: [Data
我在 Excel 文件中有一个摘要选项卡,需要查看应计选项卡才能找到 Max和 Min .我遇到的问题是有许多不同的位置/商品组合,我需要找到 Max和 Min基于位置/商品组合。位置和商品位于两个单
我有一个 Excel 表,其中包含两列感兴趣的年份和捐款。年份值为 2008,2009,2010 等... 我想获得 2009 年所有捐款中的最低金额。我试过了 MIN(IF(Year="2009",
到现在为止,我刚刚找到了为列表中多个数据帧中的列获取最大值的解决方案。 我已经将数据帧 df1, df2, df3, ..., dfn 存储在列表 dfList 中,我想获取列 df_ 的最大值$a
假设我有一个列名列表作为向量: vec=c("C1" , "C2" ,"C3"). 我知道这些列名来自数据框 df: df: C1 C2 C3 C4 C5 1 2 3 4 5 1 4
我需要计算大数组的最小值/最大值。我知道Math.max.apply() ,但在大型数组上,它会因堆栈溢出异常而失败。有什么简单的解决方案吗? 最佳答案 使用 sort() 对数组进行排序方法它使用快
例如,我有一个像这样的模型: class Record(models.Model): name = CharField(...) price = IntegerField(...)
我正在编写一个用于测试听力的简单应用,并且正在使用Audiotrack生成纯音。因为它是用于测试听力的应用程序,所以我使用非常低的音量来播放这些音调。 要设置音量,我使用音轨的 setVolume(f
Example data set 对,上面是我的数据集子段图像的链接。它以 3 列为一组,第一个是浓度,第二个是限定值,最后一个是 MDL - 并持续最多 95 个 sample (因此总共 285
我想计算 df 的每 n 行的最小值/最大值,比如 10,但是使用 df.rolling(10).max() 给出第 0-9、1-10、2-11 行的值等。我想要 0-9、10-19、20-29 等
我被问到了关于 c# 的同样问题 here我发现通过使用 linq 你可以轻松地做到这一点。 但是既然 java 中的 linq 没有其他选择,我该如何简单地做到这一点呢? 最佳答案 如果您想要类似于
我曾经使用过数组,并且知道如何对使用数值(double 和 int)的数组进行排序,但我必须使用字符串数组制作相同的应用程序。我的教授不允许我发挥“创造力”,也不允许我与其他可能有助于完成这项工作的静
我想知道通过这样的回溯获得某些事实的最大值(最年长的人)是否是个好主意: data(MaxID, MaxName, MaxAge), \+ (data(ID, Name, Age), ID \= Ma
我想计算 df 的每 n 行的最小值/最大值,比如 10,但是使用 df.rolling(10).max() 给出第 0-9、1-10、2-11 行的值等。我想要 0-9、10-19、20-29 等
我的数据如下所示: df <- tribble( ~A, ~B, 0.2, 0.1, 0.2, 0.3, 0.5, 0.1, 0.7, 0.9,
我有以下数据集 Date Category 2014-01-01 A 2014-01-02 A 2014-01-03 A 2014-01-04
我是使用 Python 进行数据分析的初学者,并且坚持以下几点: 我想使用广播/矢量化方法从各个列 (pandas.dataframe) 中找到最大值(value)。 我的数据框的快照如下: 最佳答案
C99 中是否有一个标准函数来使用给定的比较函数获取给定数组中的最小/最大元素。 类似: void* get_min(void* start,size_t size,size_t elementSiz
我是一名优秀的程序员,十分优秀!