Cod sursa(job #2081053)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 3 decembrie 2017 21:01:24
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.41 kb
#include <fstream>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdint>

using namespace std;

template<typename T, size_t grow_size=1024>
class MemoryPool {
  private:
    struct List {
        List* next;
    };

    class Buffer {
      public:
        Buffer(Buffer* to) : next(to) { }

        T* GetBlock(size_t idx) {
            return reinterpret_cast<T*>(&buff[size * idx]);
        };

        Buffer* const next;
      private:
        static constexpr size_t size = max(sizeof(T), sizeof(List));
        uint8_t buff[size * grow_size];
    };

    List* free_block = nullptr;
    Buffer* block_ptr = nullptr;
    size_t pointer = grow_size;

    MemoryPool(MemoryPool&& oth) = delete;
    MemoryPool(const MemoryPool& oth) = delete;
    MemoryPool& operator =(MemoryPool&& oth) = delete;
    MemoryPool& operator=(const MemoryPool& oth) = delete;

  public:
    MemoryPool() = default;

    ~MemoryPool() {
        while (block_ptr != nullptr) {
            Buffer* aux = block_ptr;
            block_ptr = aux->next;
            delete aux;
        }
    }
    
    T* Allocate() {
        if (free_block) {
            List* block = free_block;
            free_block = free_block->next;
            return reinterpret_cast<T*>(block);
        }

        if (pointer == grow_size) {
            block_ptr = new Buffer(block_ptr);
            pointer = 0;
        }

        return block_ptr->GetBlock(pointer++);
    }

    void Deallocate(T* pointer) {
        List* block = reinterpret_cast<List*>(pointer);
        block->next = free_block;
        free_block = block;
    }
};

template<typename T, size_t grow_size=1024>
class Allocator : private MemoryPool<T, grow_size> {
  private:
    allocator<T>* default_allocator = nullptr;
  public:
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T value_type;
    template<class U>
    struct rebind { typedef Allocator<U, grow_size> other; };

    Allocator() = default;

    template<typename U>
    Allocator(const Allocator<U, grow_size>& oth) {
        if (not is_same<T, U>::value) {
            default_allocator = new allocator<T>();
        }
    }

    ~Allocator() {
        delete default_allocator;
    }

    T* allocate(size_t n, allocator<void>::const_pointer hint=0) {
        if (default_allocator) {
            return default_allocator->allocate(n, hint);
        }
        if (n != 1 or hint) {
            throw std::bad_alloc();
        }

        return MemoryPool<T, grow_size>::Allocate();
    }

    void deallocate(T* p, size_t n) {
        if (default_allocator) {
            default_allocator->deallocate(p, n);
        } else {
            MemoryPool<T, grow_size>::Deallocate(p);
        }
    }

    void construct(T* p, const T& value) {
        new (p) T(value);
    }

    void destroy(T* p) {
        p->~T();
    }
};

int main() {
#ifdef INFOARENA
    ifstream cin("hashuri.in");
    ofstream cout("hashuri.out");
#endif

    set<int, less<int>, Allocator<int>> set_;
    int num_queries; cin >> num_queries;
    while (num_queries--) {
        int type, el; cin >> type >> el;
        if (type == 1) {
            set_.insert(el);
        } else if (type == 2) {
            set_.erase(el);
        } else {
            cout << (set_.find(el) != set_.end()) << '\n';
        }
    }
    
    return 0;
}