Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何有效地将数组的一系列值与给定的数字相乘?_C++_Arrays_Algorithm_Multiplication_Fenwick Tree - Fatal编程技术网

C++ 如何有效地将数组的一系列值与给定的数字相乘?

C++ 如何有效地将数组的一系列值与给定的数字相乘?,c++,arrays,algorithm,multiplication,fenwick-tree,C++,Arrays,Algorithm,Multiplication,Fenwick Tree,最简单的方法是对范围进行线性迭代,然后与范围内的每个数字相乘 示例:数组:{1,2,3,4,5,6,7,8,9,10}; 用2乘以索引3到索引8。假设基于一个索引 结果数组应该是:{1,2,6,8,10,12,14,16,9,10} 我知道二叉索引树可以用于“求和”部分。如何有效地将给定范围与数字相乘?您还可以逐位更新范围。() 您还可以使用段树RMQ。你可以很容易地与给定的数字相乘 关于ST和RMQ的不错的教程。 如果你真的想修改数组,你不能比简单的线性算法做得更好:你必须迭代整个范围并相应地

最简单的方法是对范围进行线性迭代,然后与范围内的每个数字相乘

示例:数组:{1,2,3,4,5,6,7,8,9,10}; 用2乘以索引3到索引8。假设基于一个索引

结果数组应该是:{1,2,6,8,10,12,14,16,9,10}


我知道二叉索引树可以用于“求和”部分。如何有效地将给定范围与数字相乘?

您还可以逐位更新范围。()

您还可以使用段树RMQ。你可以很容易地与给定的数字相乘

关于ST和RMQ的不错的教程。
如果你真的想修改数组,你不能比简单的线性算法做得更好:你必须迭代整个范围并相应地修改每个索引

如果您的意思是,您有如您所描述的更新操作和一个查询操作
查找x到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)
基本上,每个节点将只考虑子段中的乘法来存储其总和。在查询过程中,将使用影响该间隔的乘法的相关信息延迟计算其真和

然后执行一个求和查询,就像在段树上执行一个普通查询一样:只需确保将求和乘以它们或父区间的乘积即可

伪代码

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)

最初构建树的函数留作练习(可以比调用update
n
次做得更好)。

据我所知,唯一的方法是迭代向量,并应用乘法

您可以这样定义一个函数:

void VecMultiply(std::vector<int>& pVector, int Multiplier);
void vecpluply(std::vector&pVector,int乘数);
并像这样实施:

void VecMultiply(std::vector<int>& pVector, int Multiplier)
{
    for (unsigned int i = 0; i < pVector.size(); i++)
    {
        *pVector[i] *= Multiplier;
    }
}
void向量乘子(std::vector&pVector,int乘数)
{
for(无符号整数i=0;i
或者,您甚至可以使用模板传递任何内容乘以任何内容的向量:

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;
        }
    }
模板
模板
无效向量乘子(标准::向量和pVector,M乘子)
{
for(无符号整数i=0;i
您可以遵循线性方法,在
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 << " ";

在我看来,线性方法是最有效的。:)或者我不明白一些事情吗?到目前为止你尝试了什么?我尝试了一种简单的方法,迭代范围并将范围中的每个数字与给定的数字相乘。我同意莫斯科的Vlad,但你可以使用某种SIMD()。这取决于你以后如何检索这些数字(你的查询)。你能解释一下那个部分吗?我们也可以用位来更新范围。谢谢你的指导和否决票@瓦西姆·塔布拉兹(Wasim Thabraze.)您可以做得更好,如果您传递了be引用,则无需取消对参数的引用。