簡體   English   中英

找出數組中三元組i,j,k的數量,以使索引為i到j-1的元素的異或等於索引為j到k的元素的異或

[英]Find the number of triplets i,j,k in an array such that the xor of elements indexed i to j-1 is equal to the xor of elements indexed j to k

對於給定的正整數A1,A2,...,AN序列,應該找到三元組(i,j,k)的數量,使得Ai ^ Ai + 1 ^ .. ^ Aj-1 = Aj ^ Aj + 1 ^ .. Ak,其中^表示按位異或。 問題的鏈接在這里: https : //www.codechef.com/AUG19B/problems/KS1我所做的只是嘗試找到所有xor為0的子數組。解決方案有效,但是時間是二次的,因此太慢了。 這是我設法達到的解決方案。

for (int i = 0; i < arr.length; i++) {
            int xor = arr[i];
            for (int j = i + 1; j < arr.length; j++) {
                xor ^= arr[j];
                if (xor == 0) {
                    ans += (j - i);
                }
            }
        }
        finAns.append(ans + "\n");

這是基於問題描述下CiaPan的評論的O(n)解決方案:

如果索引I到J-1處的項的異或等於從J到K的異或,則從I到K的異或等於零。 對於任何這樣的子數組[I..K],I + 1和K-1之間的每個J都構成一個滿足要求的三元組。 從I到K的xor等於(從0到K的xor)xor(從0到I-1的xor)。 因此,我想您可能會發現序列中所有可能的初始部分的異或,並尋找相等的對。

函數f是主要方法。 brute_force用於驗證。

Python 2.7代碼:

import random

def brute_force(A):
  res = 0

  for i in xrange(len(A) - 1):
    left = A[i]
    for j in xrange(i + 1, len(A)):
      if j > i + 1:
        left ^= A[j - 1]
      right = A[j]
      for k in xrange(j, len(A)):
        if k > j:
          right ^= A[k]
        if left == right:
          res += 1

  return res

def f(A):
  ps = [A[0]] + [0] * (len(A) - 1)
  for i in xrange(1, len(A)):
    ps[i] = ps[i- 1] ^ A[i]

  res = 0
  seen = {0: (-1, 1, 0)}

  for  i in xrange(len(A)):
    if ps[i] in seen:
      prev_i, i_count, count = seen[ps[i]]
      new_count = count + i_count * (i - prev_i) - 1
      res += new_count
      seen[ps[i]] = (i, i_count + 1, new_count)
    else:
      seen[ps[i]] = (i, 1, 0)

  return res

for i in xrange(100):
  A = [random.randint(1, 10) for x in xrange(200)]
  f_A, brute_force_A = f(A), brute_force(A)
  assert f_A == brute_force_A
print "Done"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM