Cod sursa(job #2081060)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 3 decembrie 2017 21:12:28
Problema Hashuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.71 kb
#include <vector>
#include <algorithm>
#include <fstream>
#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 = sizeof(T) > sizeof(List) ? 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();
    }
};

constexpr int kMod = 666013;

vector<int, Allocator<int>> vec[kMod];

int main() {
#ifdef INFOARENA
    ifstream cin("hashuri.in");
    ofstream cout("hashuri.out");
#endif
    
    auto Find = [&](const int el) {
        return find(vec[el % kMod].begin(), vec[el % kMod].end(), el) != vec[el % kMod].end();
    };
    

    int num_queries; cin >> num_queries;
    while (num_queries--) {
        int type, el; cin >> type >> el;
        if (type == 1) {
            if (not Find(el)) {
                vec[el % kMod].push_back(el);
            }
        } else if (type == 2) {
            vec[el % kMod].erase(find(vec[el % kMod].begin(), vec[el % kMod].end(), el));
        } else {
            cout << (int)Find(el) << '\n';
        }
    }
    
    return 0;
}