Cod sursa(job #907967)

Utilizator mathboyDragos-Alin Rotaru mathboy Data 8 martie 2013 15:51:03
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.45 kb
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <fstream>
#include <iostream>

using namespace std;


class smen {
	int *h1;
       	int *h2;
	 
	int sz; 
	int a1, b1, a2, b2, prime, val;
	int num_maxsteps ; 
	

	bool RehashTable();
	bool InsertTable(int);
	public:
	
	smen(int n) {
		prime = 2000000011;
		h1 = new int[n]; 
		h2 = new int[n];
		
		a1 = rand() % n; 
		b1 = rand() % n;
		
		a2 = rand() % n;
		b2 = rand() % n;
		
		num_maxsteps = (int)log2(n);

		memset(h1, 0, n * sizeof(h1));
		memset(h2, 0, n * sizeof(h2));
		sz = n;

		cerr << a1 << " " << b1 << " " << a2 << " " << b2 << " " << num_maxsteps << "\n";
	}
	
	inline int get1(int);
	inline int get2(int);
	inline void tryInsertTable(int);

	inline bool FindTable(int);
	inline void EraseTable(int);
	~smen() {
		delete[] h1;
		delete[] h2;
	}
       	smen CopyTable() {
	       return *this; 
	}	       
};


inline void smen :: tryInsertTable( int y) {
	while( InsertTable(y) == false)
				for( ;RehashTable() == false; ) ; 
}
inline int smen :: get1(int x) {
	return ((1LL * a1 * x + b1 ) % prime ) % sz;
}
inline int smen :: get2(int x) {
	return ((1LL * a2 * x + b2) % prime) % sz;
}
inline bool smen :: InsertTable(int x) {
	int num_s = 0 ; 
	
		
	if( FindTable(x) ) 
		return true;
	
	while(num_s < num_maxsteps) {
		num_s += 2;
		
		if( h1[get1(x)] == 0 ) {
			h1[get1(x)] = x;
			return true;
		}
		swap(h1[get1(x)], x) ; 

		if(h2[get2(x)] == 0) {
			h2[get2(x)] = x;
			return true;
		}
		swap(h2[get2(x)] , x);
	}
	return false;
}

inline bool smen :: FindTable(int x) {
	return ( h1[ get1(x) ] == x || h2[get2(x)] == x) ; 
}
inline void smen :: EraseTable(int x) {
	if( h1[ get1(x) ] == x )
		h1[get1(x)] = 0;
	if(h2[ get2(x) ] == x)
		h2[ get2(x) ] = 0;
}
inline bool smen :: RehashTable() {
	smen next(1000000);
	
	for(int i = 0; i < sz; ++i)
		if(h1[i]) 
			if( next.InsertTable(h1[i]) == false )
				return false;
	for(int i = 0; i < sz; ++i)
		if(h2[i])
			if(next.InsertTable(h2[i]) == false)
				return false;

	*this = next.CopyTable() ;
	return true;
}


int main() {

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

	srand(time(NULL));	
	int op, x, y;

	smen num_Hash(1000000);
	
	for( fin >> op ; op--; ) {
		fin >> x >> y ; 
		
//		cerr << x << " " << y << "\n";
		if(x == 1) {
			num_Hash.tryInsertTable(y) ; 
			
		}
		
		if(x == 2)
			num_Hash.EraseTable(y);
		if(x == 3)
			fout << (int)num_Hash.FindTable(y) << "\n";
	}
	return 0;
}