gpt4 book ai didi

c++ - 快速回答子数组查询的高效算法

转载 作者:太空狗 更新时间:2023-10-29 20:52:42 24 4
gpt4 key购买 nike

前几天我遇到了一个查询相关的问题,但是我无法解决。

给定一个包含 N 个整数和一个正整数 M 的数组,您必须回答 Q 个问题。每个查询的特征为 ( i , j ),其中 ij 分别是数组的索引。在每个查询中,您必须回答存在多少对(rs)

  1. i <= r <= s <= j
  2. 索引在 [ r , s ] 中的数组元素之和可以被 M 整除。

限制:

N <= 50,000
Q <= 50,000
M <= 100

我有一个动态编程解决方案,可以在 O( N^2 ) 中预处理每个查询( rs ),但这是不够快。有没有更有效的解决方案?我对 Mo 的算法或线段树有一些想法,但我无法理解。

最佳答案

  1. 为每个 i = 1..N 计算原始数组的前缀和(假设它从 1 开始) .
    enter image description here
    Sum[r] 的等效项和 Sum[s]对于任意两个指数 rs其中 r < s表示索引在 [r+1, s] 中的数组元素的总和可以被 M 整除(并且我们需要计算区间内此类等价的数量)。这一步的时间复杂度是O(N) .

  2. 预先计算数组Count对于每个 i = 1..N, j = 0..M-1 : enter image description here
    Count[i][j]存储 Sum[len] 的次数(其中 len <= i )等于 j .这一步的时间复杂度是O(N*M) .

  3. 对于每个查询 (i, j)答案将等于: enter image description here
    对于余数的每个可能值 k我们找到D(k) - Sum[len] 的次数等于k区间内[i, j] .然后我们将 D(k) 的所有可能对的数量添加到结果中。区间边界即 D(k)*(D(k)-1)/2 .时间复杂度:O(M)对于每个查询。

复杂度:O(N) + O(N*M) + O(Q*M) = O((Q+N)*M) ,这对于给定的约束是可以的。

关于c++ - 快速回答子数组查询的高效算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45449393/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com