如何有效地将数组的一系列值与给定的数字相乘
How do I efficiently multiply a range of values of an array with a given number?
最简单的方法是线性迭代范围,并与范围中的每个数字相乘。
示例:数组:{1,2,3,4,5,6,7,8,9,10};将索引3到索引8乘以2。假设基于一个索引。
结果数组应为:{1,2,6,8,10,12,14,16,9,10};
我知道二进制索引树可以用于"answers"部分。如何有效地将给定的范围与数字相乘?
如果你想真正修改数组,你不能比天真的线性算法做得更好:你必须迭代整个范围,并相应地修改每个索引。
如果你的意思是,你有一个像你描述的更新操作和一个查询操作find the sum in the range from x to y
,那么段树可以帮助你
对于每个更新操作left, right, value
,对于具有包含在[left, right]
中的关联范围的每个节点,其和将乘以value
,因此相应地更新该值并停止递归。这也将适用于您不会递归的区间,因此,与其实际更新总和,不如在每个节点中存储其相关区间乘以了多少。
当从递归返回时,您可以根据此信息重新计算实际和。
伪码:
Update(node, left, right, value):
if [left, right] does not intersect node.associated_range:
return
if [left, right] included in node.associated_range:
node.multiplications *= value # 1 initially
return
Update(node.left, left, right, value)
Update(node.right, left, right, value)
node.sum = node.left.sum * node.left.multiplications +
node.right.sum * node.right.multiplications
基本上,每个节点将只考虑子段中的乘法来存储其和。它的真和将在查询期间通过使用有关影响该区间的乘法的信息来延迟计算。
然后执行求和查询,几乎就像对分段树进行常规查询一样:只需确保将求和乘以它们或父区间的乘积。
伪码:
Query(node, multiplications = 1, left, right):
if [left, right] does not intersect node.associated_range:
return 0
if [left, right] included in node.associated_range:
return node.sum * multiplications
return Query(node.left, multiplications * node.multiplications, left, right) +
Query(node.right, multiplications * node.multiplications, left, right)
最初构建树的函数只是一个练习(您可以比调用updaten
次做得更好(。
您可以采用线性方法,并使用类似的C++11
进行编码
std::array<int, 10> nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::for_each(nums.begin() + 2, nums.begin() + 8, [](int & n) { n *= 2; });
for (int & n : nums) std::cout << n << " ";
输出
1 2 6 8 10 12 14 16 9 10
通过BIT,您还可以更新范围。(自检范围更新(。
您也可以使用分段树RMQ。你可以很容易地与给定的数字相乘。
关于ST和RMQ的不错教程。RMQ Topcoder和分段树
据我所知,唯一的方法是迭代通过向量,并应用乘法。
你可以这样定义一个函数:
void VecMultiply(std::vector<int>& pVector, int Multiplier);
并将其实现为:
void VecMultiply(std::vector<int>& pVector, int Multiplier)
{
for (unsigned int i = 0; i < pVector.size(); i++)
{
*pVector[i] *= Multiplier;
}
}
或者,你甚至可以使用模板传递任何东西乘以任何东西的向量:
template<typename T>
template<typename M>
void VecMultiply(std::vector<T>& pVector, M Multiplier)
{
for (unsigned int i = 0; i < pVector.size(); i++)
{
*pVector[i] *= Multiplier;
}
}
也可以是向量形式:
std::vector<int> nums={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };;
int c=2;
std::transform(nums.begin()+2,nums.end(), nums.begin(), [&c](auto& n){return c*n;});
for (int & n : nums) std::cout << n << " ";
- 在C++的一系列数字中查找重复模式
- 将一系列数字映射到 CPP 中的值的简单方法
- 如何非常快速地将数字添加到 Vector 中的一系列元素中
- 根据用户输入从一系列数字中找到一个完美的数字
- 为什么这4个不同的随机数生成器函数会产生相同的一系列数字
- 将目标数字拆分为一系列数字(递归任务)
- 代码打印出一系列无意义的数字
- C++ - 计算一系列数字的数字
- 在一系列数字的间隔内计算数字
- c++程序输出一系列的数字而不是cout
- 我正在尝试创建一个程序,用户在其中输入一系列数字,并且我想列出范围之间的质数
- 用O(1)表示法求一系列数字的平均值——常数时间
- 使用一系列数字有效地初始化 std::set
- C++中一系列数字的组合
- 我怎样才能在一系列数字中找到一个缺失的数字
- 给定一系列数字报告,哪些重复和重复了多少次
- 读取一系列数字
- 在c++中使用随机数生成一系列可重复的数字
- Boost Spirit语法用于识别从一行到向量的一系列数字
- 如何有效地将数组的一系列值与给定的数字相乘