Codeforces 706D Trie树/multiset

来源:互联网 发布:香港手机网络制式 编辑:程序博客网 时间:2024/05/17 06:27

题目:http://codeforces.com/problemset/problem/706/D
题意:

+表示吧这个数加到集合中,-表示把这个数从集合中减去一次,?表示集合里面的一个y使的x^y最大

分析:

要使异或最大,那么尽量从高位使两个数不同即可。

Trie树。

#include<bits/stdc++.h>using namespace std;const int N=1e7+9;int a[N][2],cal[N];int tot;void add(int x,int y) //插入或删除一个元素{    int cur=0;    for(int i=31;i>=0;i--){        int t=(x>>i)&1;        if(!a[cur][t])a[cur][t]=tot++;        cur=a[cur][t];        cal[cur]+=y;    }}int query(int x){    int cur=0,ans=0;    for(int i=31;i>=0;i--){        int t=(x>>i)&1;        if(cal[a[cur][t^1]]){            ans+=(1<<i);            cur=a[cur][t^1];        }        else cur=a[cur][t];    }    return ans;}int main(){    int n,x;    char op;    tot=1;    add(0,1);    scanf("%d",&n);    for(int i=0;i<n;i++){        cin>>op>>x;        if(op=='+'){            add(x,1);        }        else if(op=='-'){            add(x,-1);        }        else{            printf("%d\n",query(x));        }    }    return 0;}/*Input10+ 8+ 9+ 11+ 6+ 1? 3- 8? 3? 8? 11Output11101413*/

或者可以直接用multiset模拟:

#include<bits/stdc++.h>using namespace std;const int N=1e7+9;int main(){    int n,x;    char op;    multiset<int>s;    s.insert(0);    scanf("%d",&n);    for(int i=0;i<n;i++){        cin>>op>>x;        if(op=='+'){            s.insert(x);        }        else if(op=='-'){            s.erase(s.find(x));        }        else{            int ans=0;            for(int i=31;i>=0;i--){                ans|=(~x&(1<<i));                multiset<int>::iterator it=s.lower_bound(ans);                if(it==s.end()||*it>=ans+(1<<i)){                   // cout<<ans<<endl;                    ans^=1<<i;                }            }            printf("%d\n",x^ans);        }    }    return 0;}
0 0