Cod sursa(job #1475378)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 24 august 2015 00:29:05
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.42 kb
#include <bits/stdc++.h>

using namespace std;

///---------------------------------------------------
const int BUFFER_SIZE = (1 << 14);
char buffer[BUFFER_SIZE];
int position = BUFFER_SIZE;

inline char getChar()
{
    if ( position == BUFFER_SIZE )
    {
        position = 0;
        fread(buffer, BUFFER_SIZE, 1, stdin);
    }

    return buffer[position++];
}

inline int getNr()
{
    register int a = 0;
    char ch;
    int sgn = 1;

    do
    {
        ch = getChar();

    } while ( !isdigit(ch) && ch != '-' );

    if ( ch == '-' )
    {
        sgn = -1;
        ch = getChar();
    }

    do
    {
        a = (a << 3) + (a << 1) + ch - '0';
        ch = getChar();

    } while ( isdigit(ch) );

    return a * sgn;
}
///---------------------------------------------------

class BloomFilter
{
private:

    class Bitset
    {
    private:

        unsigned long long *b;

    public:

        Bitset() : b(nullptr) {
        }

        Bitset(const int _size) : b(new unsigned long long[1 + (_size >> 6)]) {

            memset(b, 0, sizeof(b));
        }

        void set(const int p)
        {
            b[p >> 6] |= (1ULL << (p & 63));
        }

        bool test(const int p) const
        {
            return (b[p >> 6]  >> (p & 63)) & 1;
        }
    };

    int N;
    vector<int> primes;

    Bitset *filter;

public:

    BloomFilter() : N(0), primes(vector<int>()), filter(nullptr) {
    }

    BloomFilter(const vector<int> &v) : N(v.size()), primes(v), filter(new Bitset[v.size()]) {

        for (int i = 0; i < N; ++i)
            filter[i] = Bitset(primes[i]);
    }

    inline void insert(const int key)
    {
        for (int i = 0; i < N; ++i)
            filter[i].set(key % primes[i]);
    }

    inline bool find(const int key) const
    {
        for (int i = 0; i < N; ++i)
            if (filter[i].test(key % primes[i]) == false)
                return false;

        return true;
    }
};

class LinearProbing
{
public:

    LinearProbing()
    {
        table = new int[MAX_SIZE];

        for ( int i = 0; i < MAX_SIZE; ++i )
            table[i] = EMPTY;
    }

    ~LinearProbing()
    {
        delete[] table;
    }

    void insert(const int key)
    {
        int p = ((key & MOD) * PRIME) & MOD;

        while (table[p] != EMPTY && table[p] != ERASED)
            p = (p + 1) & MOD;

        table[p] = key;
    }

    bool find(const int key)
    {
        int p = ((key & MOD) * PRIME) & MOD;

        while (table[p] != EMPTY && table[p] != key)
            p = (p + 1) & MOD;

        return table[p] == key;
    }

    void erase(const int key)
    {
        int p = ((key & MOD) * PRIME) & MOD;

        while (table[p] != EMPTY && table[p] != key)
            p = (p + 1) & MOD;

        if (table[p] == key)
            table[p] = ERASED;
    }

private:

    static const int MAX_SIZE = 1 << 20;
    static const int MOD = MAX_SIZE - 1;
    static const int PRIME = 137;

    static const int EMPTY = -1;
    static const int ERASED = -2;

    int *table;
};

LinearProbing L;

int main()
{
    ifstream in("hashuri.in");
    ofstream out("hashuri.out");

    ios_base::sync_with_stdio( false );

    int N;
    in >> N;

    while ( N-- )
    {
        int tip, x;

        in >> tip >> x;

        switch(tip)
        {
            case 1: L.insert(x); break;
            case 2: L.erase(x); break;
            case 3: out << L.find(x) << "\n"; break;

            default: cerr << "Error\n";
        }
    }

    return 0;
}