Cod sursa(job #2918486)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 11 august 2022 16:57:04
Problema Heapuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.11 kb
#include <cstdio>
#include <vector>

using namespace std;

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

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

};


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

void attach(SplayNode* root, SplayNode* child, int side) {
  root->child[side] = child;
  if (child) {
    child->par = root;
  }
}

void rot(SplayNode* a) {
  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) {
  while (a->par) {
    if (a->par->par) {
      if (getSide(a) == getSide(a->par)) {
        rot(a->par);
      } else {
        rot(a);
      }
    }
    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) {
  if (root->child[1]) {
    return splayMax(root->child[1]);
  }
  return splay(root);
}

SplayNode* splayMin(SplayNode* root) {
  if (root->child[0]) {
    return splayMin(root->child[0]);
  }
  return splay(root);
}

SplayNode* join(SplayNode* a, SplayNode* b) {
  if (!a) {
    return b;
  }
  if (!b) {
    return a;
  }
  a = splayMax(a);
  attach(a, b, 1);
  return a;
}

SplayNode* root = nullptr;


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

int main() {
  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++) {
    int typ;
    scanf("%d", &typ);
    if (typ == 1) {
      int x;
      scanf("%d", &x);
      vals.push_back(x);
      ins(x);
    }
    if (typ == 2) {
      int i;
      scanf("%d", &i);
      int x = vals[i - 1];
      SplayNode* a = fnd(root, x);
      root = splay(a);
      root = join(root->child[0], root->child[1]);
      if (root) {
        root->par = nullptr;
      }
    }
    if (typ == 3) {
      root = splayMin(root);
      if (root) {
        root->par = nullptr;
      }
      printf("%d\n", root->val);
    }
  }
}