algorithm - 在特殊条件下获取集合中的最大数量

标签 algorithm data-structures set xor

我最近遇到了一个问题,我很难找到答案。 这就是问题:

考虑一组数字。输入有树形类型:

1 x
2 x
3

第一个命令将整数x 添加到集合中。 第二个意味着对于列表中的每个元素y,输入:

y = y xor x

最后一个命令打印集合中的最大数字。例如:

10
3
1 7
3
2 4
2 8
2 3
1 10
1 3
3
2 1

结果:

0
7
15

如果 n 是输入中的命令数:
和:
还有1秒的执行时间限制!


到目前为止我的解决方案: 让我们调用集合S并有一个整数m,它最初是0。如你所知:

number = number xor x xor x

这意味着如果我们对某个东西应用两次异或,那么它的效果就会相反,并且原始数字不会改变。也就是说,如果我们每次插入一个数字(命令 1),我们都会执行以下操作:

y = y xor m
add y to S

每次我们想从集合中获取一个数字时:

find y
y = y xor m
return y

如果命令二如下:

m = m xor x

然后问题就几乎解决了,因为最初保存了数字的异或版本,并且在需要时我们进行反转! 但这里的问题是找到集合中最大的数字(注意集合中的数字与原始数字不同),所以命令3正确。我不知道如何在有效的时间内做到这一点。但我有一个想法:
如果我们首先将集合中数字的二进制表示形式保存在 trie 数据结构中,也许我们可以快速找到最大的数字。我真的不知道怎么回事,但我突然想到了这个想法。 总结一下我的问题:

问题 1:
如何找到修改后的列表中最大的数字
问题2:
这个trie主意好吗?
问题3:
我如何在代码中实现它(语言在这里不是很重要)以便它可以工作时间查找?


首先解决这个问题所需的时间复杂度是多少?

感谢您阅读我的问题。

最佳答案

是的,你的想法是正确的,它可以使用二进制 trie 数据结构在 O(N log 10^9) 中解决。

这个想法是以二进制表示法存储数字,但将最大的位放在前面,因此在遍历 trie 时,我们可以选择一个导致最大答案的分支。

为了确定选择哪个分支,我们可以一点一点地确定,如果从某个 trie 节点我们有 2 个值为 0 和 1 的分支,我们选择在与 m 进行异或后给出更好结果的分支

示例代码(C++):

#include <bits/stdc++.h>
using namespace std;

int Trie[4000005][2];
int nxt = 2;

void Add(int x)
{
    bitset<32>b(x);
    int c = 1;

    for(int j=31; j>=0; j--)
        if(Trie[c][b[j]])c=Trie[c][b[j]];
    else c = Trie[c][b[j]] = nxt++;
}

int Get(int x)
{
    bitset<32>b(x),res(0);
    int c = 1;

    for(int j=31; j>=0; j--)
        if(Trie[c][!b[j]])c=Trie[c][!b[j]],res[j]=!b[j];
    else c = Trie[c][b[j]], res[j]=b[j];

    return res.to_ullong()^x;
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int q,m=0;
    cin>>q;
    Add(0);

    while(q--)
    {
        int type;
        cin>>type;
        if(type==1)
        {
            int x;
            cin>>x;
            Add(x^m);
        }
        else if(type==2)
        {
            int x;
            cin>>x;
            m^=x;
        }
        else cout<<Get(m)<<"\n";
    }
}

关于algorithm - 在特殊条件下获取集合中的最大数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59016836/

相关文章:

python - 二维字典或其他键顺序无关紧要的数据结构

arrays - 查找在线性时间内出现超过 n/4 次的所有元素

algorithm - 状态机适合解决什么样的问题?

C#:寻求快速数据结构以将像素添加到分区的 HSB 直方图

data-structures - 如何在结构内的 HashMap 中插入? [复制]

python - 如何覆盖 "set"内置?

java - 二维数组的快速散列

algorithm - 如何生成满足三角形不等式的矩阵?

javascript - Google Apps 脚本中的集合和数据结构

c++ - 如何使迭代器指向与 C++ 集中的另一个元素相同的元素?