这里写自定义目录标题
更多精彩内容
这里是带你游历编程世界的Dashcoding编程社,我是Dash/北航硕士/ICPC区域赛全国排名30+/给你呈现我们眼中的世界!
256题算法特训课,帮你斩获大厂60W年薪offer
原题
美团校招真题-小美与数组
B站动画详解
问题分析
在这道题目中,我们需要计算在经过多次操作后,数组所有元素的最终和。每次操作中,只有一个指定的元素保持不变,其余所有元素都会被翻倍。这意味着我们不能简单地模拟每次操作的结果,因为这样会导致时间复杂度过高,尤其是在操作次数 q q q 和数组大小 n n n 都很大的情况下。更高效的方式是通过差分数组来记录每个元素的翻倍次数,再通过快速幂来计算每个元素的最终值,并求出这些值的总和。同时,由于操作次数可能非常大,且数组元素的初始值也可能很大,因此在输出结果时需要对 1 0 9 + 7 10^9 + 7 109+7 取模。这道题目综合了差分数组、快速幂和模运算的知识点,考察了算法设计的高效性和准确性。
思路分析
首先,我们需要利用差分数组来记录每个元素的翻倍次数。差分数组是一种常见的技巧,它通过在某个位置进行标记,表示从这一位置开始,后续的一系列元素需要被执行相同的操作。具体来说,每次操作时,我们在差分数组中增加两个标记,一个标记从数组的第一个元素开始,表示该元素之后的所有元素都需要翻倍;另一个标记在当前操作所指定的元素位置之后,表示从此位置之后的元素不再进行翻倍。通过这种方式,我们可以快速地统计出每个元素的最终翻倍次数。接下来,我们使用快速幂的方法来计算每个元素经过翻倍后的值。快速幂的思想是通过不断地将指数进行二分,以减少计算的次数,从而高效地求出 2 k m o d ( 1 0 9 + 7 ) 2^k \mod (10^9 + 7) 2kmod(109+7) 的值。最后,将所有元素的翻倍值累加起来,得到最终的总和并对 1 0 9 + 7 10^9 + 7 109+7 取模,以避免结果过大。
算法实现
算法的实现可以分为几个主要步骤。首先,我们读取输入的数组和操作次数,然后初始化差分数组。接下来,对于每次操作,我们根据给定的位置更新差分数组。在操作完成后,通过对差分数组求前缀和的方式,计算出每个元素的翻倍次数。然后,我们利用快速幂函数计算每个元素的最终值,并将这些值累加起来得到总和。最后,对总和进行取模运算,并输出结果。在实现过程中,需要注意的是,由于数组大小和操作次数都可能非常大,因此所有的计算都必须在取模运算下进行,避免整数溢出。这个算法的核心在于如何高效地处理大规模的数据操作,以及如何通过数学方法来简化计算过程。
代码详解
在这段代码中,qpow
函数用于计算 2 k m o d ( 1 0 9 + 7 ) 2^k \mod (10^9 + 7) 2kmod(109+7),以高效地处理大规模的翻倍操作。主函数中,我们首先读取输入并初始化数组,然后使用差分数组来处理每次操作。通过对差分数组的累加,我们得到了每个元素的最终翻倍次数。最后,通过快速幂计算出每个元素的最终值,并累加得到总和,输出时取模 1 0 9 + 7 10^9 + 7