Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC target ("avx2")
- #pragma GCC optimization ("O3")
- #pragma GCC optimization ("unroint-loops")
- #pragma GCC optimize("Ofast,no-stack-protector")
- #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
- #pragma GCC optimize("unroll-loops")
- #include <bits/stdc++.h>
- #define int int64_t
- #define ull unsigned long long
- #define ld long double
- #define INF (int)2e16
- #define rng(i,a,b) for(int i=int(a);i<int(b);i++)
- #define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
- #define per(i,b) gnr(i,0,b)
- #define rep(i,b) rng(i,0,b)
- #define endl '\n'
- #define yes "YES\n"
- #define no "NO\n"
- #define F first
- #define S second
- #define all(a) a.begin(),a.end()
- #define rall(a) a.rbegin(),a.rend()
- #define __sort(x) sort(x.begin(), x.end())
- #define __rsort(x) sort(x.rbegin(), x.rend())
- #define __lcm(a, b) (int(a) * int(b) / (__gcd(int(a), int(b))))
- #define out_1arr(a, ch123) for(auto el_ : a) cout << el_ << ch123;
- #define out_2arr(a, ch123) for(auto row_ : a) {for(auto col_ : row_) cout << col_ << ch123; cout << endl;}
- #define optimize() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
- #define multitest() int ttt;cin >> ttt;rep(t_cnt, ttt)
- using namespace std;
- #ifdef LOCAL
- mt19937 tw(9450189);
- #else
- mt19937 tw(chrono::high_resolution_clock::now().time_since_epoch().count());
- #endif
- uniform_int_distribution<int> ll_distr;
- int rnd(int a, int b) { return ll_distr(tw) % (b - a + 1) + a; }
- struct Node {
- int l, r, key, priority, size;
- Node(int k = -1, int l = -1, int r = -1,
- int pr = rnd(1, 1000000000)): key(k), priority(pr), l(l),
- r(r), size(1) {}
- };
- const int NMAX = 2e6;
- vector<Node> t(NMAX);
- int cur_new = 0, root = -1;
- int get_size(int v) {
- if (v == -1)
- return 0;
- return t[v].size;
- }
- void update_size(int v) {
- if (v == -1) return;
- t[v].size = get_size(t[v].l) + get_size(t[v].r) + 1;
- }
- int merge(int l, int r) {
- if (l == -1) return r;
- if (r == -1) return l;
- if (t[l].priority < t[r].priority) {
- t[l].r = merge(t[l].r, r);
- update_size(l);
- return l;
- } else {
- t[l].l = merge(l, t[r].l);
- update_size(r);
- return r;
- }
- }
- void split(int v, int key, int &l, int &r) {
- if (v == -1)
- l = r = -1;
- else if (t[v].key < key) {
- split(t[v].r, key, t[v].r, r);
- l = v;
- } else {
- split(t[v].l, key, l, t[v].l);
- r = v;
- }
- update_size(v);
- }
- int insert(int v, int cur) {
- if (v == -1) {
- return cur;
- } else if (t[cur].priority < t[v].priority) {
- split(v, t[cur].key, t[cur].l, t[cur].r);
- update_size(cur);
- return cur;
- }
- if (t[cur].key < t[v].key) {
- t[v].l = insert(t[v].l, cur);
- } else {
- t[v].r = insert(t[v].r, cur);
- }
- update_size(v);
- return v;
- }
- int erase(int v, int key) {
- if (v == -1) {
- return v;
- }
- if (t[v].key == key) {
- return merge(t[v].l, t[v].r);
- }
- if (key < t[v].key) {
- t[v].l = erase(t[v].l, key);
- } else {
- t[v].r = erase(t[v].r, key);
- }
- update_size(v);
- return v;
- }
- bool contains(int v, int key) {
- if (v == -1) {
- return 0;
- } else if (t[v].key == key) {
- return 1;
- }
- if (key > t[v].key) {
- return contains(t[v].r, key);
- } else {
- return contains(t[v].l, key);
- }
- }
- int find_greater(int v, int x) {
- if (v == -1) {
- return INF;
- }
- if (t[v].key > x) {
- return min(find_greater(t[v].l, x), t[v].key);
- } else {
- return find_greater(t[v].r, x);
- }
- }
- int find_lower(int v, int x) {
- if (v == -1) {
- return -INF;
- }
- if (t[v].key < x) {
- return max(find_lower(t[v].r, x), t[v].key);
- } else {
- return find_lower(t[v].l, x);
- }
- }
- int find_kth(int v, int k) {
- if (v == -1)
- return -INF;
- int sz = get_size(t[v].l);
- if (k == sz) {
- return t[v].key;
- } else if (k < sz) {
- return find_kth(t[v].l, k);
- } else {
- return find_kth(t[v].r, k - sz - 1);
- }
- }
- void insert(int x) {
- cur_new++;
- t[cur_new - 1] = {x};
- root = insert(root, cur_new - 1);
- }
- void erase(int x) {
- root = erase(root, x);
- }
- int find_greater(int x) {
- return find_greater(root, x);
- }
- int find_lower(int x) {
- return find_lower(root, x);
- }
- bool contains(int x) {
- return contains(root, x);
- }
- int find_kth(int x) {
- return find_kth(root, x);
- }
- void solve() {
- string type;
- while (cin >> type) {
- int x;
- cin >> x;
- if (type == "insert") {
- if (!contains(x)) {
- insert(x);
- }
- } else if (type == "delete") {
- erase(x);
- } else if (type == "exists") {
- if (contains(x)) {
- cout << "true\n";
- } else {
- cout << "false\n";
- }
- } else if (type == "next") {
- int res = find_greater(x);
- if (res == INF) {
- cout << "none\n";
- } else {
- cout << res << endl;
- }
- } else if (type == "prev") {
- int res = find_lower(x);
- if (res == -INF) {
- cout << "none\n";
- } else {
- cout << res << endl;
- }
- } else if (type == "kth") {
- x--;
- int res = find_kth(x);
- if (res == -INF) {
- cout << "none\n";
- } else {
- cout << res << endl;
- }
- }
- cout.flush();
- }
- }
- int32_t main() {
- #ifdef LOCAL
- freopen("..\\input.txt","r",stdin);
- freopen("..\\output.txt","w",stdout);
- freopen("..\\error.txt","w",stderr);
- auto start_time = clock();
- cerr << setprecision(3) << fixed;
- #endif
- optimize();
- //multitest()
- solve();
- #ifdef LOCAL
- auto end_time = clock();
- cerr << "Execution time: " << (end_time - start_time) * (int) 1e3 / CLOCKS_PER_SEC << " ms\n";
- #endif
- }
Advertisement
Add Comment
Please, Sign In to add comment