Codeforces Round #367 (Div. 2) [D] Vasiliy's Multiset(01字典树模板)

    xiaoxiao2025-03-27  14

    D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output

    Author has gone out of the stories about Vasiliy, so here is just a formal task description.

    You are given q queries and a multiset A, initially containing only integer 0. There are three types of queries:

    "+ x" — add integer x to multiset A. "- x" — erase one occurrence of integer x from multiset A. It's guaranteed that at least one x is present in the multiset A before this query. "? x" — you are given integer x and need to compute the value , i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer x and some integer y from the multiset A.

    Multiset is a set, where equal elements are allowed.

    Input

    The first line of the input contains a single integer q (1 ≤ q ≤ 200 000) — the number of queries Vasiliy has to perform.

    Each of the following q lines of the input contains one of three characters '+', '-' or '?' and an integer xi (1 ≤ xi ≤ 109). It's guaranteed that there is at least one query of the third type.

    Note, that the integer 0 will always be present in the set A.

    Output

    For each query of the type '?' print one integer — the maximum value of bitwise exclusive OR (XOR) of integer xi and some integer from the multiset A.

    Example input 10 + 8 + 9 + 11 + 6 + 1 ? 3 - 8 ? 3 ? 8 ? 11 output 11 10 14 13 Note

    After first five operations multiset A contains integers 089116 and 1.

    The answer for the sixth query is integer  — maximum among integers , , , and .

    题意:对于一个集合有三种操作:

    1.添加一个数字x

    2.删除一个数字x

    3.给你一个数字x,在集合中找出一个数y使x^y最大,并输出y

    这道题开始以为线段树,后来发现01字典树更好用一些,可惜自己并不会写……

    对于这道题有一个贪心原则,就是找每一位尽量和当前数不一样的,异或才会更大

    先贴一下代码,可以当01字典树模板用

    #include<cstdio> #include<iostream> using namespace std; const int maxn=30; int n,tot=1; struct wk{int NEXT[4],son;}trie[5000000]; void insert(int x){ int cur=1,i; for(i=maxn;i>=0;i--){ int y=(x>>i)&1; trie[cur].son++; if(!trie[cur].NEXT[y]) trie[cur].NEXT[y]=++tot; cur=trie[cur].NEXT[y]; } trie[cur].son++; } void del(int x){ int cur=1,i; for(i=maxn;i>=0;i--){ int y=(x>>i)&1; if(!trie[cur].NEXT[y])return; trie[cur].son--; cur=trie[cur].NEXT[y]; } trie[cur].son--; } int find(int x){ int cur=1,i,ans=0; for(i=maxn;i>=0;i--){ int y=1^((x>>i)&1); int temp=trie[cur].NEXT[y]; if(!temp||(!trie[temp].son))y^=1; ans|=y<<i; cur=trie[cur].NEXT[y]; } return ans; } int main(){ int x; char ch; cin>>n; insert(0); while(n--){ cin>>ch>>x; if(ch=='+')insert(x); if(ch=='-')del(x); if(ch=='?')printf("%d\n",x^find(x)); } }

    转载请注明原文地址: https://ju.6miu.com/read-1297452.html
    最新回复(0)