集合内的最小异或对(使用set)
求数组集合内的最小异或对
结论:
一个集合内的最小异或对,一定是排序后的两个向量相邻元素。秩序记录其相邻元素的异或值即可。
一个set存储元素值,另一个元素存储异或值。
增加元素时,删除该元素前驱和后继异或,增加上该元素和前驱后继的异或
//#include<bits/srdc++.h>
#include<set>
#include<iostream>
using namespace std;
const int N = 2e5 + 10;
int st[32*N][2],idx;
int main()
{
multiset<int> s, v;
int n;
cin >> n;
while(n--)
{
string st;
int x;
cin >> st;
//两个集合,一个存储数,另一个存储相邻的元素异或值,已知最小异或值为两相邻元素的异或
if(st[0]=='A')
{
scanf("%d", &x);
auto p = s.lower_bound(x);
if(p!=s.begin())
{
v.insert(x ^ *prev(p));
}
else if(p!=s.end())
{
v.insert(x ^ *p);
}
else if(p!=s.end()&&p!=s.begin())
{
v.erase(v.lower_bound(*p ^ *prev(p)));
}
s.insert(x);
}
else if(st[0]=='D')
{
scanf("%d", &x);
s.erase(s.lower_bound(x));
auto p = s.lower_bound(x);
if(p!=s.begin())
{
v.erase(v.lower_bound(*p ^ *prev(p)));
}
else if(p!=s.end())
{
v.erase(v.lower_bound(x^*p));
}
else if(p!=s.end()&&p!=s.end())
{
v.insert(*p ^ *prev(p));
}
}
else
{
cout <<* v.begin() << endl;
}
}
}