CF706D Vasiliy's Multiset(字典樹的刪除)
阿新 • • 發佈:2021-07-21
思路:
求異或的最大值容易想到01字典樹,只需要再維護刪除操作就好。
加一個\(a\)陣列記錄一下有多少個節點經過了這個點,刪除的時候如果這是最後一個經過該點的節點,就刪除他的父節點向下指的指標。用map維護一下每個數出現的次數,字典樹只維護種類。
注意要先將0插入字典樹,集合裡沒有數的時候,x的異或最大值依舊是x。
程式碼:
// Problem: CF706D Vasiliy's Multiset // Contest: Luogu // URL: https://www.luogu.com.cn/problem/CF706D // Memory Limit: 250 MB // Time Limit: 4000 ms // Author:Cutele0626 // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll>PLL; typedef pair<int, int>PII; typedef pair<double, double>PDD; #define I_int ll inline ll read() { ll x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-')f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } inline void out(ll x){ if (x < 0) x = ~x + 1, putchar('-'); if (x > 9) out(x / 10); putchar(x % 10 + '0'); } inline void write(ll x){ if (x < 0) x = ~x + 1, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); puts(""); } #define read read() #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) #define multiCase int T;cin>>T;for(int t=1;t<=T;t++) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i<(b);i++) #define per(i,a,b) for(int i=(a);i>=(b);i--) #define perr(i,a,b) for(int i=(a);i>(b);i--) ll ksm(ll a, ll b, ll p) { ll res = 1; while(b) { if(b & 1)res = res * a % p; a = a * a % p; b >>= 1; } return res; } const ll inf =1e15; #define PI acos(-1) const int maxn=100000+10; const int N = 200000+10, M = 3000000; int n; int son[N*32][2], idx,a[N*32]; void insert(int x) { int p = 0; for (int i = 31; i >= 0; i -- ) { int &s = son[p][x >> i & 1]; if (!s) s = ++ idx; p = s; a[p]++; } } int search(int x) { int p = 0, res = 0; for (int i = 31; i >= 0; i -- ) { int s = (x >> i) & 1; if (son[p][!s]) { res |= (1 << i); p = son[p][!s]; } else p = son[p][s]; } return res; } void del(int x){ int p = 0; for (int i = 31; i >= 0; i -- ) { int &s = son[p][x >> i & 1]; int tt=p; p = s; a[p]--; if(a[p]==0) son[tt][x>>i&1]=0; } } int main(){ n=read; map<int,int>mp; insert(0); while(n--){ char op[2];cin>>op; int x=read; if(op[0]=='+'){ mp[x]++; if(mp[x]==1) insert(x); } else if(op[0]=='-'){ mp[x]--; if(mp[x]==0) del(x); } else printf("%d\n",search(x)); } return 0; }