Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define task "xquery"
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <algorithm>
- #include <cassert>
- using namespace std;
- using ll = long long;
- using ld = long double;
- constexpr int N = 1e5 + 5;
- struct node
- {
- int cnt, v;
- node *child[2];
- node()
- {
- child[0] = child[1] = NULL;
- cnt = v = 0;
- }
- };
- int q, t[N], x[N];
- int XOR;
- void Read()
- {
- cin >> q;
- for (int i = 1; i <= q; ++i)
- cin >> t[i] >> x[i];
- }
- void Sub_1()
- {
- vector<int> ans;
- for (int i = 1; i <= q; ++i)
- {
- if (t[i] == 0)
- ans.emplace_back(x[i]);
- else if (t[i] == 1)
- {
- for (int j = 0; j < (int)ans.size(); ++j)
- if (ans[j] == x[i])
- {
- ans[j] = ans.back();
- ans.pop_back();
- break;
- }
- }
- else if (t[i] == 2)
- {
- for (auto &j : ans)
- j ^= x[i];
- }
- else
- {
- ll sum(0);
- for (int j = 0; j < x[i]; ++j)
- sum += ans[j];
- cout << sum << "\n";
- }
- sort(ans.begin(), ans.end());
- }
- }
- #define bit(i, x) (((x) >> (i)) & 1)
- struct Trie
- {
- node root;
- void Add(int x, int v)
- {
- node *a = &root;
- int id(16);
- while (1)
- {
- if (id == -1)
- {
- ++(a->cnt);
- a->v += v;
- return;
- }
- if (!(a->child[bit(id, x)]))
- a->child[bit(id, x)] = new node;
- ++(a->cnt);
- a->v += v;
- a = a->child[bit(id, x)];
- --id;
- }
- }
- bool Erase(node *a, int x, int id, int v)
- {
- if (id == -1)
- {
- if (a->cnt > 0)
- {
- --(a->cnt);
- a->v -= v;
- return true;
- }
- return false;
- }
- if (!(a->child[bit(id, x)]))
- return false;
- if (!Erase(a->child[bit(id, x)], x, id - 1, v))
- return false;
- --(a->cnt);
- a->v -= v;
- return true;
- }
- void Erase(int x, int v)
- {
- Erase(&root, x, 16, v);
- }
- int Get(int k)
- {
- node *a = &root;
- int id(16);
- int ans(0);
- bool ok = k == 47;
- while (1)
- {
- if (id == -1)
- {
- ans += min(k, a->v);
- break;
- }
- int cof[] = {0, 1};
- if (bit(id, XOR))
- swap(cof[0], cof[1]);
- if (a->child[cof[0]] && a->child[cof[0]]->cnt >= k)
- {
- a = a->child[cof[0]];
- }
- else
- {
- if (a->child[cof[0]])
- {
- ans += a->child[cof[0]]->v;
- k -= a->child[cof[0]]->cnt;
- }
- //assert(a->child[cof[1]] != NULL);
- a = a->child[cof[1]];
- }
- --id;
- }
- return ans;
- }
- } f[20];
- void Add(int x)
- {
- for (int i = 0; i < 17; ++i)
- f[i].Add(x, bit(i, x));
- }
- void Erase(int x)
- {
- for (int i = 0; i < 17; ++i)
- f[i].Erase(x, bit(i, x));
- }
- ll Get(int k)
- {
- if (k == 0)
- return 0;
- ll ans(0);
- for (int i = 0; i < 17; ++i)
- {
- int v = f[i].Get(k);
- ans += (bit(i, XOR) ? k - v : v) * (1 << i);
- }
- return ans;
- }
- void Sub_2()
- {
- XOR = 0;
- for (int i = 1; i <= q; ++i)
- {
- if (t[i] == 0)
- Add(x[i] ^ XOR);
- else if (t[i] == 1)
- Erase(x[i] ^ XOR);
- else if (t[i] == 2)
- XOR ^= x[i];
- else
- cout << Get(x[i]) << "\n";
- }
- }
- int32_t main()
- {
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- if (fopen(task ".INP", "r"))
- {
- freopen(task ".INP", "r", stdin);
- freopen(task ".OUT", "w", stdout);
- }
- Read();
- if (q <= 1000)
- Sub_1();
- else
- Sub_2();
- }
Advertisement
Add Comment
Please, Sign In to add comment