Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (01trie樹)

分析:

01trie樹經典應用,找異或最大值。這裏只是多了一個刪除操作,只需要記錄前綴數,然後增刪就可以了。
可以在每一個葉子節點記錄當前數是多少。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define pr(x) cout << #x << ": " << x << "  " 
#define pl(x) cout << #x << ": " << x << endl;
typedef long long LL;
#define MAX 200009

struct jibancanyang
{

    int ch[32*MAX][2];
    int cnt[32*MAX];
    LL val[32*MAX];
    int sz;

    void init(){
        memset(ch[0], 0, sizeof(ch[0]));
        memset(cnt, 0, sizeof(cnt));
        sz = 1;
    }

    void inser(LL a, int t){
        int u=0;
        for(int i=32;i>=0;i--){
            int c=((a>>i)&1);
            if(!ch[u][c]){
                memset(ch[sz], 0, sizeof(ch[sz]));
                val[sz]=0;
                ch[u][c]=sz++;
            }
            u=ch[u][c];
            cnt[u] += t;
        }
        val[u]=a;
    }

    LL query(LL a){
        int u=0;
        for(int i=32;i>=0;i--){
            int c=((a>>i)&1);
            if(cnt[ch[u][c ^ 1]]) u=ch[u][c^1];
            else u=ch[u][c];
        }
        return val[u] ^ a;
    }

    void fun() {
        int T;
        scanf("%d%*c", &T);
        init();
        inser(0, 1);
        while (T--) {
            char op;
            int x;
            scanf("%c %d%*c", &op, &x);
            if (op == '+') inser(x, 1);
            else if (op == '-')  inser(x, -1);
            else printf("%lld\n", query(x));
        }
    }

}ac;

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif
    ac.fun();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章