【问题标题】:Sum of bitwise OR of max and min element of every subsets of given array给定数组的每个子集的最大和最小元素的按位或总和
【发布时间】:2018-10-31 10:27:34
【问题描述】:

给定一个数组,我必须找到给定数组的大小大于或等于 2 的所有可能子集的最大值和最小元素的所有按位或的总和。 例如- [1,3,5] 大小 >=2 的子集是 {1,3}{1,5}{3,5}{1,3,5}

{1,3}-此子集中最大和最小元素的二元或=3

{1,5}-此子集中最大和最小元素的二元或=5

{3,5}-此子集中最大和最小元素的二元或=7

{1,3,5}-此子集中最大和最小元素的二元或=5

所以总和是 3+5+7+5=20。

我尝试使用给定集合的所有可能子集的按位或的总和进行修改,但无法绘制逻辑。

注意:数组的大小为 10^5。

【问题讨论】:

  • 我不确定您的问题是什么。
  • 我必须编写一个满足逻辑的程序。但是由于数组的顺序非常大,遍历每个集合以找到最小值和最大值将是 2^n 的顺序,这是巨大的。我想知道是否还有其他算法
  • 子集的大小有什么限制?
  • 这是目前正在进行的在线评委比赛中的问题!

标签: algorithm bit-manipulation


【解决方案1】:

考虑到所有数字从 1 到 1000 的伪代码:

int count[1001];
int accumulated[1001];

for each element in array:
    count[element]++;

diff_nums = []

for i = 1 to 1000:
    accumulated[i] = accumulated[i - 1] + count[i];
    if (count[i] > 0):
        diff_nums.push(i);

result = 0;

for i = 0 to diff_nums.size():
    i_el = diff_nums[i]
    result += i * (2^(count[i_el]) - count[i_el] - 1)         
    for j = i + 1 to diff_nums.size():
        j_el = diff_nums[j]
        numbers_between_i_and_j = accumulated[j_el - 1] - accumulated[i_el]
        amount_of_subsets_between_i_and_j = 2^(numbers_between_i_and_j)
        amount_of_subsets_with_at_least_1_i = (2^count[i_el] - 1)
        amount_of_subsets_with_at_least_1_j = (2^count[j_el] - 1)

        result += (i_el OR j_el) * amount_of_subsets_between_i_and_j * amount_of_subsets_with_at_least_1_i * amount_of_subsets_with_at_least_1_j

D 是 N 中唯一数的数量,其复杂度为:

O(D^2 log n) 假设我们用模数对 log n 求幂

【讨论】:

  • 太棒了!这个解决方案太棒了!我只是不明白一件事。 result += i * (2^(count[i_el]) - count[i_el] - 1) => 这将始终将 i/2 添加到 result?为什么我们需要这样做?
  • @Raghav 在第二个循环中,我们正在考虑以 diff_nums[i] 为最小值和 diff_nums[j] 为最大值的所有子集情况。但是,我们没有考虑子集仅由 diff_nums[i] 组成的情况。那条线负责处理这些情况。使用相同数字的子集数量将是 2^(该数字的数量)。然后我们减去 1,因为子集是空的,我们也减去那个数字的数量,因为我们不考虑只有 1 个元素的子集。
  • 知道了,队长。谢谢!
【解决方案2】:

对数组进行排序。循环遍历集合中的所有元素对。将这些元素作为 min 和 max 的任何子集都将给出相同的贡献。由于数组已排序,因此可以通过元素的索引来计算此类子集的数量。然后,您可以将这些子集的组合贡献计算为子集的按位或次数。

【讨论】:

  • 循环虽然所有对已经是 O(n^2) 这对于 n = 10^5 来说太多了
  • 10^10 对于现代计算机来说并不算多。我认为这在午休时间应该是可行的。
  • 能否简化为O(nlog)解?
  • @Shewta 你能链接原始问题吗?这个问题的解决方案可以是一个 100000 位的数字,您似乎不太可能必须回答这个问题
  • @juvian..这只是口头问我,但有人提到我们必须将结果修改为 10^9+7
猜你喜欢
  • 1970-01-01
  • 2022-10-12
  • 1970-01-01
  • 2016-05-27
  • 2014-08-07
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 2016-12-28
相关资源
最近更新 更多