Cod sursa(job #608773)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 17 august 2011 23:16:13
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.17 kb
#include <fstream>
#include <iostream>
#include <set>
#include <vector>
#include <stdio.h>
#include <string.h>

using namespace std;

#define HASH_SIZE	666013

#define MAX_BITS	31

typedef unsigned int uint32;

struct TrieData
{
	TrieData *parent;
	TrieData *child[2];
};

class CTrie
{
public:
	CTrie()
	{
		Trie.parent = 0;
		memset(Trie.child, 0, 2*sizeof(TrieData*));
	}
	
	inline void addElement(const uint32 num)
	{
		uint32 i;
		int childIndex;
		TrieData *ptr = &Trie;
		
		for (i = 1<<MAX_BITS; i; i>>=1)
		{
			childIndex = !(!(num & i));

			if (!ptr->child[childIndex])
			{
				ptr->child[childIndex] = allocElement();
				
				ptr->child[childIndex]->parent = ptr;
			}
			
			ptr = ptr->child[childIndex];
		}
	}
	
	void eraseElement(const uint32 num)
	{
		uint32 i;
		TrieData *ptr = &Trie, *parent;
		int childIndex;
		
		for (i = 1<<MAX_BITS; i; i>>=1)
		{
			childIndex = !(!(num & i));
			
			if (!ptr->child[childIndex])
			{
				return;
			}
			
			ptr = ptr->child[childIndex];
		}
		
		i = 1;
		
		while ( ((parent = ptr->parent) != NULL) && !checkHasChildren(ptr))
		{
			delElement(ptr);
			parent->child[!(!(num & i))] =  NULL;
			ptr = parent;
		}
	}
	
	long findElement(const uint32 num) const
	{
		uint32 i;
		const TrieData *ptr = &Trie;
		int childIndex;
		
		for (i = 1<<MAX_BITS; i; i>>=1)
		{
			childIndex = !(!(num & i));

			if (!ptr->child[childIndex])
			{
				return 0;
			}
			
			ptr = ptr->child[childIndex];
		}

		return 1;
	}
	
	long findMaximizingElement(const uint32 num, uint32& val) const
	{
		uint32 i;
		int childIndex;
		const TrieData *ptr = &Trie;
		
		val = 0;

		for (i = 1<<MAX_BITS; i; i>>=1)
		{
			childIndex = !(num & i);
			
			if (ptr->child[childIndex])
			{
				val += i;
				ptr = ptr->child[childIndex];
			}
			else
				ptr = ptr->child[!childIndex];
		}
		
		return 0;
	}

private:
	TrieData Trie;
	
	inline bool checkHasChildren(const TrieData* elem) const
	{
		return (elem->child[0] && elem->child[1]);
	}
	
	inline TrieData* allocElement() const
	{
		TrieData *elem = new TrieData;

		elem->parent = 0;
		memset(elem->child, 0, 2*sizeof(TrieData*));
		
		return elem;
	}
	
	inline void delElement(TrieData *elem) const
	{
		delete elem;
	}
};

//set<int> table[HASH_SIZE];
//CTrie table[HASH_SIZE];
vector<int> table[HASH_SIZE];

inline vector<int>::iterator findValue(vector<int>& table, const int x)
{
	vector<int>::iterator it;
	
	for (it = table.begin(); it != table.end(); ++it)
	{
		if (*it == x)
		{
			return it;
		}
	}
	
	return table.end();
}

inline void insertValue(vector<int> *table, const int x)
{
	const int index = x % HASH_SIZE;
	vector<int>::iterator it;
	
	if ((it = findValue(table[index], x)) == table[index].end())
	{
		table[index].push_back(x);
	}
}

inline void eraseValue(vector<int> *table, const int x)
{
	const int index = x % HASH_SIZE;
	vector<int>::iterator it;
	
	if ((it = findValue(table[index], x)) != table[index].end())
	{
		table[index].erase(it);
	}
}

int main()
{
	int N, op, x;
	fstream fin("hashuri.in", fstream::in);
	fstream fout("hashuri.out", fstream::out);
	
	fin >> N;
	//cout << N << endl;
	
	//cout << sizeof(set<int>) << " " << sizeof(vector<int>) << " " << sizeof(TrieData) << endl;
	
	for (int i=0; i<N; ++i)
	{
		fin >> op >> x;
		
		switch (op)
		{
			case 1:
			{
				//table[x % HASH_SIZE].insert(x);
				//table[x % HASH_SIZE].addElement(x);
				insertValue(table, x);
			}; break;
			
			case 2:
			{
				//table[x % HASH_SIZE].erase(x);
				//table[x % HASH_SIZE].eraseElement(x);
				eraseValue(table, x);
			}; break;
		
			case 3:
			{
				//fout << ((table[x % HASH_SIZE].find(x) != table[x % HASH_SIZE].end()) ? 1 : 0) << "\n";
				//fout << table[x % HASH_SIZE].findElement(x) << "\n";
				const int index = x % HASH_SIZE;
				vector<int>::iterator it;
				
				if ((it = findValue(table[index], x)) == table[index].end())
				{
					fout << 0 << "\n";
				}
				else
				{
					fout << 1 << "\n";
				}
			}; break;
		}
	}
	
	fin.close();
	fout.close();
	
	getchar();
	return 0;
}