Cod sursa(job #399889)

Utilizator Pepelea_FlaviuFlaviu Pepelea Pepelea_Flaviu Data 21 februarie 2010 10:26:11
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.44 kb
# include <cstdio>
# include <algorithm>
# include <vector>

using namespace std;

# define FIN "hashuri.in"
# define FOUT "hashuri.out"
# define MAX_N 1000005
# define max(a, b) ((a) > (b) ? (a) : (b))

struct arb
{
       int size, val, cnt;
       arb *st, *dr;

       arb(int value, int sz, arb *left, arb *right, int ct)
       {
            size = sz;
            cnt = ct;
            val = value;
            st = left; dr = right;
       }
} *Tree;

int N, i, op, val, S, fat, value, vf, Rez;

    int sz(arb *p)
    {
        if (!p) return 0;
        return p -> size;
    }

    int update_size(arb *p, arb *q)
    {
        return max(sz(p), sz(q)) + 1;
    }

    void rotsst(arb *&R)
    {
         arb *p;

         p = R->dr;
         R -> size = update_size(R -> st, p -> st);
         p -> size = update_size(R, p -> dr);
         R -> dr = p -> st;
         p -> st = R;
         R = p;
    }

    void rotsdr(arb *&R)
    {
         arb *p;

         p = R -> st;
         R -> size = update_size(R -> dr, p -> dr);
         p -> size = update_size(R, p -> st);
         R -> st = p -> dr;
         p -> dr = R;
         R = p;
    }

    void rotdst(arb *&R)
    {
         rotsdr(R -> dr); rotsst(R);
    }

    void rotddr(arb *&R)
    {
         rotsst(R -> st); rotsdr(R);
    }

    void balance(arb *&R)
    {
         int bnd;

         bnd = sz(R -> st) - sz(R -> dr);

         if (bnd == -2) // left rotation
            if (sz(R -> dr -> st) <= sz(R -> dr -> dr)) rotsst(R);
            else rotdst(R);

         else if (bnd == 2) // right rotation
            if (sz(R -> st -> dr) <= sz(R -> st -> st)) rotsdr(R);
            else rotddr(R); 
    }

    void insert(arb *&R, int val)
    {           
         if (!R) R = new arb(val, 1, NULL, NULL, 1);
         else
         {
              if (val < R -> val) insert(R -> st, val);
              else insert(R -> dr, val);

              R -> size = update_size(R -> st, R -> dr);

              balance(R);
         }
    }

    int search(arb *R, int val)
    {
        if (!R) return 0;

        if (R -> val == val) return 1;

        if (val < R -> val) return search(R -> st, val);
        else return search(R -> dr, val);
    }

    void erase(arb *&R, int val)
    {
         arb *p;

         if (!R) return;

         if (R -> val == val && R -> size == 1)
         {
             p = R; R = NULL; delete(p); return; }

         if (R -> val == val)
         {    
              if (R -> st && R -> dr)
              {
                   if (sz(R -> st) > sz(R -> dr)) rotsdr(R), erase(R -> dr, val);
                   else rotsst(R), erase(R -> st, val);
              }
              else if (R -> st) { p = R; R = R -> st; delete(p); }
              else {p = R; R = R -> dr; delete(p); }
         }
         else if (val < R->val) erase(R -> st, val);
         else erase(R -> dr, val);

         R->size = update_size(R -> st, R -> dr);
         balance(R);
    }

    int main()
    {
        freopen(FIN, "r", stdin);
        freopen(FOUT, "w", stdout);

        scanf("%d", &N);
        int op, x;
        for (i = 1; i <= N; ++i)
        {
            scanf("%d%d", &op, &x);
            if (op == 1) insert(Tree, x);
            if (op == 2) erase(Tree, x);
            if (op == 3) printf("%d\n", search(Tree, x));
        }

        return 0;
    }