集合内的最小异或对(使用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;
        }
    }
}
                    
                
                
            
        
浙公网安备 33010602011771号