集合内的最小异或对(使用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;
        }
    }
}


posted on 2023-03-26 13:58  rain_wind_read  阅读(135)  评论(0编辑  收藏  举报