以X的间隔查找整数乘积并更新位置' i'在N个查询的数组中

时间:2016-06-08 04:21:40

标签: arrays algorithm data-structures

我给出了一个长度最大为10^5&的整数数组。我想对数组进行以下操作。

1→更新任何位置i的数组值。 (1 <= i <= n)

2→从索引0, X, 2X, 3X, 4X.... (J * X <= n)

获取编号的产品

操作次数最多为10^5

是否有log n方法来回答查询和更新值。

1 个答案:

答案 0 :(得分:1)

(最初的想法是使用Segment Tree,但我认为不需要......)

N = 10^5, A:= original array of size N

当我们说下面的索引时,我们使用基于0的表示法

创建一个长度最大为B的整数数组M = NlgN

第一个整数等于A[0];

接下来N个整数是A的索引1,2,3 ... N;我称之为第1组

接下来N / 2个整数是指数2,4,6 ......;我称之为第2组

下一个N / 3整数3,6,9 ....我称之为第3组

以下是可视化B

的示例

B = [A[0] | A[1], A[2], A[3], A[4] | A[2], A[4] | A[3] | A[4]]

我认为原来的想法可以使用,不用甚至使用细分树。 (当您考虑操作2时,我们总是会在B而不是任何范围上查询特定范围,这是过度的,即我们不需要那么多的灵活性和复杂性来维护数据结构)

您可以创建上述新数组B,同时创建另一个长度为CM

的数组C[i] := products of Group i

对于操作1,只需使用O(# factors of i)查看您需要更新的组,并更新BC中的值(即C[x]/old B[y] *new B[y]

对于操作2,只输出相应的C[i]

不确定我是不是错了但是这应该更快并且应该通过判断,如果最初的想法是正确的但是得到了TLE

由于OP增加了一个新条件:对于操作2,我们还需要乘以A [0],因此我们可以特殊处理它。这是我的想法:

为操作1声明一个新变量z = A[0],如果它正在更新索引0,则更新此变量;对于操作2,使用上述相同方法进行查询,然后再乘以z

我已更新我的回答,所以现在我只使用B的第一个元素来表示A[0]

示例

A = {1,4,6,2,8,7}


B = {1 | 4,6,2,8,7 | 6,8 | 2 | 8 | 7 }  // O(N lg N)


C = {1 | 2688 | 48 | 2 | 8 | 7 } // O (Nlg N)

factorization for all possible index X (X is the index, so <= N) // O(N*sqrt(N)) 


opeartion 1:

update A[4] to 5: factors = 1,2,4  // Number of factors of index, ~ O(sqrt(N))
which means update Group 1,2,4   i.e. the corresponding elements in B & C

to locate the corresponding elements in B & C maybe a bit tricky, 
but that should not increase the complexity

B = {1 | 4,6,2,5,7 | 6,5 | 2 | 5 | 7 }    // O(sqrt(N))
C = {1 | 2688 | 48/8*5 | 2 | 8/8*5 | 7 }  // O(sqrt(N))


update A[0] to 2:
B = {2 | 4,6,2,5,7 | 6,5 | 2 | 5 | 7 }  // O(1)
C = {2 | 2688/8*5 | 48/8*5 | 2 | 8/8*5 | 7 }  // O(1)



// Now A is actually {2,4,6,2,5,7}

operation 2:

X = 3
C[3] * C[0] = 2*2 = 4  // O(1)


X = 2
C[2] * C[0] = 30*2 = 60  // O(1)