Cod sursa(job #1672938)

Utilizator Ionut.popescuLiviu Rebreanu Ionut.popescu Data 3 aprilie 2016 12:10:33
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 7.51 kb
#include<bits/stdc++.h>

template <class Te>
class SBTnode
{
public:
    template <class T>
    friend class SBTree;
    SBTnode<Te> *p, *left, *right;
    Te key;
	unsigned int Size;
	unsigned int account;


    SBTnode(Te _key)
	{
        key =_key;
        Size = 1;
        account = 1;
        left = NULL;
        right = NULL;
    };
};

template <class T>
class SBTree
{
public:
		inline void LeftRotate(SBTnode<T> * x);
		inline void RightRotate(SBTnode<T> * x);
		inline SBTnode<T>* DeleteSuccessor(SBTnode<T> * x);
		inline void Empty(SBTnode<T> * &x);
		inline bool Insert(T & k , SBTnode<T> * &z );
		inline SBTnode<T>* Search(SBTnode<T>* x , T & k);
		SBTnode<T> *Root , * Nil;
		unsigned int NUM;

		SBTree()
		{
			Nil = new SBTnode<T>(0);
			Nil->Size = 0;
			Nil->account = 0;
			Nil->left = Nil;
			Nil->right = Nil;
			NUM = 0;
			Root = Nil;
		};

		~SBTree()
		{
			delete Nil;
			Empty();
		};

		inline void Insert(T  k);
		inline void Delete(T  k);
		inline void Maintain(SBTnode<T> * x , bool IsRight);
		inline SBTnode<T>* Search(T & k);
		inline SBTnode<T>* Successor(SBTnode<T> * x);
		inline SBTnode<T>* Predecessor(SBTnode<T> * x);
		inline SBTnode<T>* Minimum(SBTnode<T> * x);
		inline SBTnode<T>* Maximum(SBTnode<T> * x);
		inline void  Print(SBTnode<T> * &x);
		inline void  Print();
		inline void  Empty();
		inline unsigned int Num();
};


template <class T>
void SBTree<T>::LeftRotate(SBTnode<T> * x)
{
	SBTnode<T> *y = x->right;
	x->right = y->left;
	if(y->left != Nil)
	{
		y->left->p =x;
	};
	y->p = x->p;
	if(x->p == Nil)
	{
		Root = y;
	}else{
	    if(x == x->p->left)
	    {
	    	x->p->left = y;
	    }else{
	    	x->p->right = y;
	    };
	};
	x->p = y;
	y->left = x;
	y->Size = x->Size;
	x->Size = x->left->Size + x->right->Size + 1;
}

template <class T>
void SBTree<T>::RightRotate(SBTnode<T> * x)
{
	SBTnode<T> *y = x->left;
	x->left = y->right;
	if(y->right != Nil)
	{
		y->right->p =x;
	};
	y->p = x->p;
	if(x->p == Nil)
	{
		Root = y;
	}else{
	    if(x == x->p->right)
	    {
	    	x->p->right = y;
	    }else{
	    	x->p->left = y;
	    };
	};
	x->p = y;
	y->right = x;
	y->Size = x->Size;
	x->Size = x->left->Size + x->right->Size + 1;
}

template <class T>
void SBTree<T>::Insert(T  k)
{
	SBTnode<T> *x = Root, *y = Nil;
	while(x != Nil)
	{
		if(k == x->key)
	    {
		    x->account++;
		    NUM++;
		    x = x->p;
		    while(x != Nil)
		    {
		    	x->Size--;
		    	x = x->p;
		    };
		    return;
	    };
	    x->Size++;
		y = x;
		if(k < x->key)
		{
			x = x->left;
		}else{
			x = x->right;
		};
	};
	SBTnode<T> * z = new SBTnode<T>(k);
	z->p = y;
	if(y == Nil)
	{
		Root = z;
	}else{
		if(k < y->key)
		{
			y->left = z;
		}else{
			y->right = z;
		};
	};
	z->left = Nil;
	z->right = Nil;
	while(y != Nil)
	{
		Maintain(y , k >= y->key);
		y = y->p;
	};
}

template <class T>
void SBTree<T>::Delete(T  k)
{
	SBTnode<T> *z = Root, *w = Nil;
	while(k != z->key && z != Nil)
	{
		z->Size--;
		w = z;
		if(k < z->key)
		{
			z = z->left;
		}else{
			z = z->right;
		};
	};
	if(z == Nil)
	{
		while(w != Nil)
		{
			w->Size++;
			w = w->p;
		};
	}else{
		if(z->account > 1)
		{
			z->account--;
			NUM--;
			while(w != Nil)
		    {
			    w->Size++;
			    w = w->p;
		    };
			return;
		};
		SBTnode<T> *y, *x;
	    if(z->left == Nil || z-> right == Nil)
        {
	        y = z;
        }else{
	        y = DeleteSuccessor(z);
        };
        if(y->left != Nil)
        {
	        x = y->left;
        }else{
	        x = y->right;
        };
        x->p = y->p;
        if(y->p == Nil)
        {
	        Root = x;
        }else{
            if(y == y->p->left)
            {
    	        y->p->left = x;
            }else{
    	        y->p->right = x;
            };
        };
        if(y != z)
        {
	        z->key = y->key;
	        z->account = y->account;
        };
        delete y;
	};

}

template <class T>
SBTnode<T>* SBTree<T>::DeleteSuccessor(SBTnode<T> * x)
{
	x->Size--;
	x = x->right;
	while(x->left != Nil)
	{
		x->Size--;
		x = x->left;
	};
	return x;
}


template <class T>
void SBTree<T>::Maintain(SBTnode<T> * x , bool IsRight)
{
	if(IsRight)
	{
		if(x->right->right->Size > x->left->Size)
		{
		    LeftRotate(x);
		}else{
			if(x->right->left->Size > x->left->Size)
			{
				RightRotate(x->right);
				LeftRotate(x);
			}else{
				return;
			};
		};
	}else{
		if(x->left->left->Size > x->right->Size)
		{
		    RightRotate(x);
		}else{
			if(x->left->right->Size > x->right->Size)
			{
				LeftRotate(x->left);
				RightRotate(x);
			}else{
				return;
			};
		};
	};
	Maintain(x->p->left,false);
	Maintain(x->p->right,true);
	Maintain(x->p,true);
	Maintain(x->p,false);
}

template <class T>
SBTnode<T>* SBTree<T>::Successor(SBTnode<T> * x)
{
	if(x->right != Nil)
	    return Minimum(x->right);
	SBTnode<T> *y = x->p;
	while(y != Nil && x == y->right)
	{
		x = y;
		y = y->p;
	};
	return y;
}


template <class T>
SBTnode<T>* SBTree<T>::Predecessor(SBTnode<T> * x)
{
	if(x->right != Nil)
	    return Minimum(x->right);
	SBTnode<T> *y = x->p;
	while(y != Nil && x == y->right)
	{
		x = y;
		y = y->p;
	};
	return y;
}

template <class T>
SBTnode<T>* SBTree<T>::Minimum(SBTnode<T> * x)
{
	while(x->left != Nil)
	{
		x = x->left;
	};
	return x;
}

template <class T>
SBTnode<T>* SBTree<T>::Maximum(SBTnode<T> * x)
{
	while(x->right != Nil)
	{
		x = x->right;
	};
	return x;
}

template <class T>
SBTnode<T>* SBTree<T>::Search(T & k)
{
	return Search(Root , k);
}

template <class T>
SBTnode<T>* SBTree<T>::Search(SBTnode<T>* x , T & k)
{
	while(x != Nil && k != x->key)
	{
		if(k < x->key)
		{
			x = x->left;
		}else{
			x = x->right;
		};
	};
	return x;
}

template <class T>
void SBTree<T>::Print(SBTnode<T> * &x)
{
	if(x->left != Nil)
	    Print(x->left);
	for(int i = 0 ; i < x->account ; i++)
	{
	    std::cout<<x->key<<std::endl;
	};
	if(x->right != Nil)
	    Print(x->right);
}

template <class T>
void SBTree<T>::Print()
{
	if(Root == Nil)
	{
		std::cout<<"Empty tree!"<<std::endl;
		return;
	};
	Print(Root);
}


template <class T>
void SBTree<T>::Empty()
{
	if(Root != Nil)
	{
	    Empty(Root);
	    Root = Nil;
	    NUM = 0;
	};
}

template <class T>
void SBTree<T>::Empty(SBTnode<T> * &x)
{
	if(x->left != Nil)
	    Empty(x->left);
	if(x->right != Nil)
	    Empty(x->right);
	delete x;
}

template <class T>
unsigned int SBTree<T>::Num()
{
	return (Root->Size + NUM);
}

#define BUFF 252587
char buff[BUFF];
int pos = BUFF;

inline char getChar() {
    if (pos == BUFF) {
        fread(buff, 1, BUFF, stdin);
        pos = 0;
    }
    return buff[pos++];
}

inline int readInt() {
    int q = 0;
    char c;
    do {
        c = getChar();
    } while (!isdigit(c));
    do {
        q = (10 * q) + (c - '0');
        c = getChar();
    } while (isdigit(c));
    return q;
}

int main() {
    freopen("hashuri.in", "r", stdin);
    freopen("hashuri.out", "w", stdout);

    int T = readInt();
    SBTree <int> Q;

    while (T--) {
        int op = readInt(), x = readInt();
        if (op == 1) {
            Q.Insert(x);
        } else if (op == 2) {
            Q.Delete(x);
        } else {
            putchar((Q.Search(x)->key == x) + '0');
            putchar('\n');
        }
    }
    fclose(stdout);
	return 0;
}