Cod sursa(job #1938931)

Utilizator BrandonChris Luntraru Brandon Data 25 martie 2017 12:31:11
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.34 kb
#include <cstdlib>
#include <fstream>
#include <cassert>

using namespace std;

ifstream fin ("hashuri.in");
ofstream fout ("hashuri.out");

int type, x;
int n;

inline int Random()  {
  return rand() % 128 + (1 << 7) * (rand() % 128) + (1 << 14) * (rand() % 128) + (1 << 21) * rand() % 128;
}

class TreapType {
public:
  int key, val, cnt;
  TreapType* lfSon;
  TreapType* rgSon;
  TreapType* parent;

  TreapType(int _val = 0, int _cnt = 0, int _key = Random(), TreapType* _lfSon = nullptr, TreapType* _rgSon = nullptr, TreapType* _parent = nullptr) {
    val = _val;
    cnt = _cnt;
    key = _key;
    lfSon = _lfSon;
    rgSon = _rgSon;
    parent = _parent;
  }

  bool find(int valSr) {
    if (val == valSr) {
      return true;
    }

    if (lfSon != nullptr and valSr < val) {
      return lfSon->find(valSr);
    }

    if (rgSon != nullptr and valSr > val) {
      return rgSon->find(valSr);
    }

    return false;
  }

  //FIX ROTATIONS!!!!!!!!!!!!!!!!!!!!!!!
  //rotate son in parameter
  inline TreapType* rotateTrig(TreapType* currSon) {
    TreapType ans = *(currSon->rgSon);
    TreapType* ansPtr = &ans;

    ansPtr->lfSon = currSon;
    ansPtr->lfSon->rgSon = currSon->rgSon->lfSon;

    return ansPtr;
  }

  inline TreapType* rotateCounterTrig(TreapType* currSon) {
    TreapType ans = *(currSon->lfSon);
    TreapType* ansPtr = &ans;

    ansPtr->rgSon = currSon;
    ansPtr->rgSon->lfSon = currSon->lfSon->rgSon;

    return ansPtr;
  }
};

TreapType* Rt;

void Insert(int valSr, TreapType* node = Rt) {
  if (node->val == valSr) {
    ++node->cnt;
    return;
  }

  if (node->lfSon != nullptr and valSr < node->val) {
    Insert(valSr, node->lfSon);
  }
  else if (node->rgSon != nullptr and valSr > node->val) {
    Insert(valSr, node->rgSon);
  }
  else if (valSr < node->val) {
    node->lfSon = new TreapType(valSr, 1);
    node->lfSon->parent = node;
  }
  else {
    node->rgSon = new TreapType(valSr, 1);
    node->rgSon->parent = node;
  }

  if (node->lfSon != nullptr and node->lfSon->key < node->key) {
    if (node->parent->lfSon == node) {
      node->parent->lfSon = node->parent->rotateCounterTrig(node);
    }
    else {
      node->parent->rgSon = node->parent->rotateCounterTrig(node);
    }
  }
  else if (node->rgSon != nullptr and node->rgSon->key <= node->key) {
    if (node->parent->lfSon == node) {
      node->parent->lfSon = node->parent->rotateTrig(node);
    }
    else {
      node->parent->rgSon = node->parent->rotateTrig(node);
    }
  }
}

void DeleteNode(TreapType* node = Rt) {
  if (node->lfSon != nullptr and node->lfSon->key < node->rgSon->key) {
    //node->parent->rotateCounterTrig(node);
    if (node->parent->lfSon == node) {
      node->parent->lfSon = node->parent->rotateCounterTrig(node);
    }
    else {
      node->parent->rgSon = node->parent->rotateCounterTrig(node);
    }
    DeleteNode(node->rgSon);
  }
  else if (node->rgSon != nullptr and node->rgSon->key <= node->lfSon->key) {
    //node->parent->rotateTrig(node);
    if (node->parent->lfSon == node) {
      node->parent->lfSon = node->parent->rotateTrig(node);
    }
    else {
      node->parent->rgSon = node->parent->rotateTrig(node);
    }
    DeleteNode(node->lfSon);
  }
  else {
    if (node == node->parent->lfSon) {
      node->parent->lfSon = nullptr;
    }
    else {
      node->parent->rgSon = nullptr;
    }

    delete node;
  }
}

void Erase(int valSr, TreapType* node = Rt) {
  if (node->val == valSr) {
    // --node->cnt;
    DeleteNode(node);
    return;
  }

  if (node->lfSon != nullptr and valSr < node->val) {
    Erase(valSr, node->lfSon);
  }
  else if (node->rgSon != nullptr and valSr > node->val) {
    Erase(valSr, node->rgSon);
  }
}

int main() {
  fin >> n;
  Rt = new TreapType;
  Rt->key=0;
  Rt->parent=new TreapType;
  Rt->parent->lfSon=Rt;
  Rt->parent->rgSon=Rt;

  for (int i = 1; i <= n; ++i) {
    fin >> type >> x;
    // if (Rt->rgSon != nullptr) {
    //   fout << Rt->rgSon->val << " 2 " << '\n';
    // }
    if (type == 1) {
      Insert(x);
      // fout << Rt->rgSon->val << " 1 " << '\n';
    }
    else if (type == 2) {
      Erase(x);
    }
    else if (type == 3) {
      // fout << Rt->rgSon->val << '\n';
      fout << Rt->find(x) << '\n';
    }
  }
  return 0;
}