Cod sursa(job #2728549)

Utilizator om6gaLungu Adrian om6ga Data 23 martie 2021 13:26:28
Problema Hashuri Scor 100
Compilator c-32 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <stdio.h>
#include <string.h>

int i, j, N;


__attribute__((always_inline)) unsigned int lowbias32(unsigned int x) {
    x ^= x >> 16;
    x *= 0x7feb352d;
    x ^= x >> 15;
    x *= 0x846ca68b;
    x ^= x >> 16;
    return x;
}
/*
// inverse
uint32_t
lowbias32_r(uint32_t x)
{
    x ^= x >> 16;
    x *= 0x43021123;
    x ^= x >> 15 ^ x >> 30;
    x *= 0x1d69e2a5;
    x ^= x >> 16;
    return x;
}*/

struct bucket {
	unsigned int capacity;
	unsigned int count;
	unsigned int *members;
};

typedef struct bucket bucket;
bucket *hashtable[512];
bucket *b;
unsigned int pos;

__attribute__((always_inline)) int binary_search(unsigned int val, unsigned int *a, unsigned int n) {
    int start = 0;
    int end = n - 1;
    int mid;

    while (start <= end) {
        mid = (start + end)>>1;
        if (a[mid] == val)
            return mid;
        (a[mid] < val) ? (start = mid + 1) : (end = mid - 1);
    }
    return end + 1;
}

__attribute__((always_inline)) void op_add(unsigned int index, unsigned int n) {
	b = hashtable[index];
	pos = binary_search(n, b->members, b->count), i;
	
	if (b->members[pos] == n) {
		return;
	}
	if (b->count == b->capacity) {
		b->members = realloc(b->members, b->capacity<<3);
		b->capacity <<= 1;
	}
	if (pos < b->count - 1) {
		memmove(b->members+pos+1, b->members+pos, (b->count-pos)<<2);
		b->members[pos] = n;
	}
	else {
		b->members[b->count] = b->members[b->count-1];
		b->members[b->count - ((n < b->members[b->count-1])?1:0)] = n;
	}
	b->count++;
}
__attribute__((always_inline)) void op_remove(unsigned int index, unsigned int n) {
	b = hashtable[index];
	pos = binary_search(n, b->members, b->count);
	
	if (b->members[pos] != n) {
		return;
	}
	if (pos < b->count-1) {
		memmove(b->members+pos, b->members+pos+1, (b->count-pos-1)<<2);
	}
	b->members[b->count-1] = 0;
	b->count--;
}

char output[2000001];
int oindex;
__attribute__((always_inline)) void op_question(unsigned int index, unsigned int n) {
	b = hashtable[index];
	pos = binary_search(n, b->members, b->count);
	//printf("%s\n", b->members[pos] == n ? "1" : "0");
	output[oindex++] = '0' + (b->members[pos] == n);
	output[oindex++] = '\n';
}

void main() {
	unsigned int n, o, flag;
	freopen("hashuri.in", "r", stdin);
	freopen("hashuri.out", "w", stdout);
	unsigned int index;
	void *op_fct[] = {op_add, op_remove, op_question};
	
	for (i = 0; i < 512; i++) {
		hashtable[i] = malloc(sizeof(bucket));
		hashtable[i]->members = calloc(1300, sizeof(unsigned int));
		hashtable[i]->capacity = 1300;
		hashtable[i]->count = 0;
	}   
	
	scanf("%d", &N);
	i = N;
	while (1) {
		i--;
		scanf("%u %u", &o, &n);
		index = (lowbias32(n) & 0x1ff);
		//if (o == 1)
		((void (*)(unsigned int, unsigned int))op_fct[o-1])(index, n);
		if (i == 0)
	        break;
	}
	printf(output);

	return;
}