Cod sursa(job #2918485)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 11 august 2022 16:54:57
Problema Heapuri Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.67 kb
#include <bits/stdc++.h>

using namespace std;

bool debug = 0;

struct SplayNode {
  int val;
  SplayNode* child[2];
  SplayNode* par;

  SplayNode() {
    val = 0;
    child[0] = child[1] = par = nullptr;
  }

};


int getSide(SplayNode* a) {
  assert(a->par);
  return (a->par->child[1] == a);
}


void inner_print(SplayNode* root) {
  if (!root) {
    return;
  }
  inner_print(root->child[0]);
  cout << root->val << " ";
  inner_print(root->child[1]);
}

void attach(SplayNode* root, SplayNode* child, int side) {
  assert(root);

  root->child[side] = child;
  if (child) {
    child->par = root;
  }
}



void rot(SplayNode* a) {
  assert(a->par);

  SplayNode* p = a->par;
  int side = getSide(a);

  if (p->par) {
    attach(p->par, a, getSide(p));

  } else {
    a->par = nullptr;
  }
  attach(p, a->child[!side], side); /// can I swap this two lines??
  attach(a, p, !side); /// can I swap this two lines??

}

SplayNode* splay(SplayNode* a) {
  if (debug) {
    ///cout << "\t\t\t\t\t\t a = " << a << "\n";
  }
  while (a->par) {
   /// cout << "a = " << a << " " << a->par << " " << a->par->par << "\n";
    if (a->par->par) {
      if (getSide(a) == getSide(a->par)) {
        rot(a->par);
  //      cout << "A\n";

//        cout << "a = " << a << " " << a->par << " " << a->par->par << "\n";
      } else {
        rot(a);
    //    cout << "B\n";

      }

     // exit(0);
    }
    rot(a);

  }
  return a;
}

SplayNode* ins(SplayNode* root, SplayNode* new_value) {
  if (!root) {
    splay(new_value);
    return new_value;
  }
  if (!root->child[0] && new_value->val <= root->val) {
    attach(root, new_value, 0);

    return root;
  }
  if (!root->child[1] && new_value->val >= root->val) {
    attach(root, new_value, 1);
    return root;
  }
  if (new_value->val <= root->val) {
    root->child[0] = ins(root->child[0], new_value);
    return root;
  } else {
    root->child[1] = ins(root->child[1], new_value);
    return root;
  }
}

SplayNode* fnd(SplayNode* root, int x) {
  if (!root) {
    return nullptr;
  }
  if (x == root->val) {
    return root;
  }
  if (x <= root->val) {
    return fnd(root->child[0], x);
  } else {
    return fnd(root->child[1], x);
  }
}

SplayNode* splayMax(SplayNode* root) {
  assert(root);
  if (root->child[1]) {
    return splayMax(root->child[1]);
  }
  ///cout << "ici\n";
  return splay(root);
}

SplayNode* splayMin(SplayNode* root) {
///  cout << "splay min : " << root << "\n";
  assert(root);
  if (root->child[0]) {
    return splayMin(root->child[0]);
  }
  debug = 1;
  return splay(root);
}

SplayNode* join(SplayNode* a, SplayNode* b) {
  if (!a) {
    return b;
  }
  if (!b) {
    return a;
  }
  ///cout << "st2\n";
  a = splayMax(a);
  ///cout << "dr2\n";
  attach(a, b, 1);
  return a;
}

SplayNode* root = nullptr;

void print() {
  cout << " ---> ";
  inner_print(root);
  cout << "\n";
}


void ins(int val) {
  SplayNode* new_value = new SplayNode;
  new_value->val = val;
  root = ins(root, new_value);
  if (root) {
    root->par = nullptr;
  }
}

set<int> s;

void ps() {
  cout << " ###- ";
  for (auto &x : s) {
    cout << x << " ";
  }
  cout << "\n";
}

int main() {
  /**ins(1);
  ins(-100);
  ins(7);
  ins(3);
  ins(-50);
  print();
  **/

  ///freopen ("___input___.txt", "r", stdin);
  freopen ("heapuri.in", "r", stdin);

  ///freopen ("heapuri.out", "w", stdout);

  int tt;
  scanf("%d", &tt);
  vector<int> vals;

  for (int tc = 1; tc <= tt; tc++) {
   /// cout << "tc = " << tc << "\n";
    int typ;
    scanf("%d", &typ);
    assert(1 <= typ && typ <= 3);

    if (typ == 1) {
      int x;
      scanf("%d", &x);
      vals.push_back(x);
      s.insert(x);
      ins(x);
    }
    if (typ == 2) {
      int i;
      scanf("%d", &i);
      int x = vals[i - 1];
    ///  cout << "tc = " << tc << "\n";
     /// assert(s.count(x));
     /// s.erase(x);
      SplayNode* a = fnd(root, x);
    ///  cout << "st\n";
      assert(a);
      root = splay(a);
      ///cout << "st\n";
      root = join(root->child[0], root->child[1]);

      if (root) {
        root->par = nullptr;
      }
      ///cout << "dr\n";
    }
    if (typ == 3) {
      assert(root);
      assert(!s.empty());
      root = splayMin(root);
      if (root) {
        root->par = nullptr;
      }
      assert(root);
      printf("%d\n", root->val);


      ///cout << root->val << " ";
    ///  cout << root->val << " vs " << *s.begin() << "\n";
    }
    continue;
    print();
    ps();
    cout << " ------------------------------ \n";
  }
}