library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub yuruhi/library

:heavy_check_mark: test/PersistentQueue.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/persistent_queue"
#include "./../DataStructure/PersistentQueue.cpp"
#include <iostream>
#include <vector>
using namespace std;

int main() {
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);

	int q;
	cin >> q;
	vector<PersistentQueue<int>> s(q + 1);
	for (int i = 1; i <= q; ++i) {
		int com, t;
		cin >> com >> t;
		++t;
		if (com == 0) {
			int x;
			cin >> x;
			s[i] = s[t].push(x);
		} else {
			cout << s[t].front() << endl;
			s[i] = s[t].pop();
		}
	}
}
#line 1 "test/PersistentQueue.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/persistent_queue"
#line 2 "DataStructure/PersistentArray.cpp"
#include <array>
#include <vector>
#include <memory>

template <class T, std::size_t LOG> class PersistentArray {
public:
	using value_type = T;
	using const_reference = const value_type&;
	static constexpr std::size_t CHILD_SIZE = 1 << LOG;

private:
	struct node_type;
	using node_ptr = std::shared_ptr<node_type>;
	struct node_type {
		value_type value;
		std::array<node_ptr, CHILD_SIZE> child;
	};

	static value_type get(std::size_t i, node_ptr p) {
		if (!p) {
			return value_type();
		} else if (i == 0) {
			return p->value;
		} else {
			return get(i >> LOG, p->child[i & (CHILD_SIZE - 1)]);
		}
	}
	static node_ptr set(std::size_t i, const_reference val, node_ptr p) {
		node_ptr result = p ? std::make_shared<node_type>(*p) : std::make_shared<node_type>();
		if (i == 0) {
			result->value = val;
		} else {
			std::size_t index = i & (CHILD_SIZE - 1);
			result->child[index] = set(i >> LOG, val, result->child[index]);
		}
		return result;
	}
	static void destructive_set(std::size_t i, const_reference val, node_ptr& p) {
		if (!p) {
			p = std::make_shared<node_type>();
		}
		if (i == 0) {
			p->value = val;
		} else {
			std::size_t index = i & (CHILD_SIZE - 1);
			destructive_set(i >> LOG, val, p->child[index]);
		}
	}

	node_ptr root;
	PersistentArray(node_ptr _root) : root(_root) {}

public:
	PersistentArray() : root() {}
	PersistentArray(const std::vector<value_type>& v) : root() {
		for (std::size_t i = 0; i < v.size(); ++i) {
			destructive_set(i, v[i]);
		}
	}
	value_type get(std::size_t i) const {
		return get(i, root);
	}
	value_type operator[](std::size_t i) const {
		return get(i);
	}
	std::vector<value_type> to_a(std::size_t n) const {
		std::vector<value_type> result(n);
		for (std::size_t i = 0; i < n; ++i) {
			result[i] = get(i);
		}
		return result;
	}
	PersistentArray set(std::size_t i, const_reference val) const {
		return PersistentArray(set(i, val, root));
	}
	void destructive_set(std::size_t i, const_reference val) {
		destructive_set(i, val, root);
	}
};
#line 3 "DataStructure/PersistentQueue.cpp"
#include <cassert>

template <class T> class PersistentQueue {
public:
	using value_type = T;
	using data_type = PersistentArray<value_type, 2>;

private:
	data_type data;
	size_t begin, end;  // [begin, end)
	PersistentQueue(const data_type& _data, size_t _begin, size_t _end)
	    : data(_data), begin(_begin), end(_end) {}

public:
	PersistentQueue() : data(), begin(0), end(0) {}
	bool empty() const {
		return begin == end;
	}
	size_t size() const {
		return end - begin;
	}
	value_type front() const {
		assert(!empty());
		return data[begin];
	}
	value_type back() const {
		assert(!empty());
		return data[end - 1];
	}
	value_type operator[](size_t i) const {
		assert(i < size());
		return data[begin + i];
	}
	value_type at(size_t i) const {
		return operator[](i);
	}
	PersistentQueue push(const T& val) const {
		return PersistentQueue(data.set(end, val), begin, end + 1);
	}
	PersistentQueue pop() const {
		assert(!empty());
		return PersistentQueue(data.set(begin, value_type()), begin + 1, end);
	}
};
#line 3 "test/PersistentQueue.test.cpp"
#include <iostream>
#line 5 "test/PersistentQueue.test.cpp"
using namespace std;

int main() {
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);

	int q;
	cin >> q;
	vector<PersistentQueue<int>> s(q + 1);
	for (int i = 1; i <= q; ++i) {
		int com, t;
		cin >> com >> t;
		++t;
		if (com == 0) {
			int x;
			cin >> x;
			s[i] = s[t].push(x);
		} else {
			cout << s[t].front() << endl;
			s[i] = s[t].pop();
		}
	}
}
Back to top page