Cod sursa(job #1568151)

Utilizator space.foldingAdrian Soucup space.folding Data 13 ianuarie 2016 22:15:22
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
struct HT {
	struct E {
		int Key;
		int T;
		int V;
		E() : T(0) {}
	};
	std::vector<E> _table;
	unsigned int _mask;

	HT(unsigned int N) {
		unsigned int n = N;
		while (n & (n + 1)) {
			n |= (n + 1);
		}
		// Make it bigger for sparser collisions
		// minimum 65k elements will need to 255k buckets
		// with 90% access of first time hash, 99% second next bucket...
		n |= (n + 1);
		_table.resize(size_t(n) + 1);
		_mask = n;
	}
	inline unsigned int hash(unsigned long long h) {
		h ^= h >> 33;
		h *= 0xff51afd7ed558ccdLL;
		h ^= h >> 33;
		h *= 0xc4ceb9fe1a85ec53LL;
		h ^= h >> 33;
		return h;
	}

	bool find(int key) {
		auto h = hash(key);

		while (true) {
			h = h & _mask;
			if (_table[h].T == 0 || _table[h].T == 1) {
				return false;
			}
			else if (_table[h].Key == key) {
				return true;
			}
			h++;
		}
	}

	void insert(int key) {
		auto h = hash(key);

		while (true) {
			h = h & _mask;
			if (_table[h].T == 0) {
				_table[h].T = 2;
				_table[h].Key = key;
				return;
			}
			else if (_table[h].Key == key) {
				// Double insert
				return;
			}
			h++;
		}
	}

	void remove(int key) {
		auto h = hash(key);
		while (true) {
			h = h & _mask;
			if (_table[h].T == 0) {
				return;
			}
			else if (_table[h].Key == key) {
				_table[h].T = 1;
				return;
			}
			h++;
		}
	}
};

char buffer[164000000];

int main() {

	FILE *in, *out;
	char *pread = buffer, *pwrite = buffer;


	in = fopen("hashuri.in", "rb");
	out = fopen("hashuri.out", "wb");

	fread(buffer, 1, 164000000, in);
	int n, offset;	
	sscanf(pread, "%d%n", &n, &offset);
	pread += offset;

	HT ht(n);

	for (int i = 0; i < n; i++) {
		int op, c;
		sscanf(pread, "%d%d%n", &op, &c, &offset);
		pread += offset;

		if (op == 1) {
			ht.insert(c);
		}
		else if (op == 2) {
			ht.remove(c);			
		}
		else if (op == 3) {
			if (ht.find(c)) {
				sprintf(pwrite, "1\n");
				pwrite += 2;
			}
			else {
				sprintf(pwrite, "0\n");
				pwrite += 2;
			}
		}
	}
	*pwrite = 0;
	fwrite(buffer, 1, pwrite - buffer, out);
	return 0;
}