Created
February 27, 2016 13:37
-
-
Save plasma-effect/d8a95eb7a514c3991475 to your computer and use it in GitHub Desktop.
競プロで使ってたやつ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//ここからテンプレート | |
#if 1 | |
#include<iostream> | |
#include<vector> | |
#include<list> | |
#include<algorithm> | |
#include<utility> | |
#include<type_traits> | |
#include<tuple> | |
#include<memory> | |
#include<iterator> | |
#include<string> | |
#include<functional> | |
#include<list> | |
#include<array> | |
#include<complex> | |
namespace utility | |
{ | |
template<class Range>std::size_t size(Range const& r) | |
{ | |
return r.size(); | |
} | |
template<class Type, std::size_t I>constexpr std::size_t size(Type const(&)[I]) | |
{ | |
return I; | |
} | |
template<class Iterator>struct iterator_range | |
{ | |
Iterator first; | |
Iterator last; | |
Iterator begin()const | |
{ | |
return first; | |
} | |
Iterator end()const | |
{ | |
return last; | |
} | |
std::size_t size()const | |
{ | |
return std::distance(first, last); | |
} | |
}; | |
template<class Iterator>auto front(iterator_range<Iterator>const& range) | |
{ | |
return *range.first; | |
} | |
template<class Iterator>auto back(iterator_range<Iterator>const& range) | |
{ | |
return *std::prev(range.last); | |
} | |
template<class Iterator>iterator_range<Iterator>make_iterator_range(Iterator first, Iterator last) | |
{ | |
return iterator_range<Iterator>{first, last}; | |
} | |
template<class Return, class Argument, class Func>class memoization_t;//recursion only | |
template<class Return, class Func, class... Ts>class memoization_t<Return, std::tuple<Ts...>, Func> | |
{ | |
std::shared_ptr<std::vector<std::pair<std::tuple<Ts...>, Return>>> memo; | |
Func func; | |
public: | |
Return operator()(Ts const&... args)const | |
{ | |
auto t = std::make_tuple(args...); | |
for (auto const& p : *memo) | |
{ | |
if (p.first == t) | |
return p.second; | |
} | |
auto ret = func(std::cref(*this), args...); | |
memo->emplace_back(t, ret); | |
return ret; | |
} | |
memoization_t(Func fun) : | |
memo(std::make_shared<std::vector<std::pair<std::tuple<Ts...>, Return>>>()), | |
func(fun) {} | |
memoization_t(memoization_t&&) = default; | |
memoization_t(memoization_t const&) = default; | |
memoization_t& operator=(memoization_t&&) = default; | |
memoization_t& operator=(memoization_t const&) = default; | |
~memoization_t() = default; | |
}; | |
template<class Return, class ArgumentTuple, class Func>memoization_t<Return, ArgumentTuple, Func> make_memoization(Func func) | |
{ | |
return memoization_t<Return, ArgumentTuple, Func>(func); | |
} | |
template<class Type>struct irange_t | |
{ | |
Type first; | |
Type last; | |
struct iterator :std::iterator<std::forward_iterator_tag, Type> | |
{ | |
Type num; | |
iterator& operator++() | |
{ | |
++num; | |
return *this; | |
} | |
iterator operator++(int) | |
{ | |
return iterator(num++); | |
} | |
Type operator*()const | |
{ | |
return num; | |
} | |
iterator(Type val) :num(val) {} | |
iterator(iterator&&) = default; | |
iterator(iterator const&) = default; | |
iterator& operator=(iterator&&) = default; | |
iterator& operator=(iterator const&) = default; | |
~iterator() = default; | |
bool operator==(iterator const& rhs)const | |
{ | |
return rhs.num == this->num; | |
} | |
bool operator!=(iterator const& rhs)const | |
{ | |
return rhs.num != this->num; | |
} | |
}; | |
iterator begin()const | |
{ | |
return iterator(first); | |
} | |
iterator end()const | |
{ | |
return iterator(last); | |
} | |
}; | |
template<class Type>irange_t<Type> irange(Type first, Type last) | |
{ | |
return irange_t<Type>{first, last}; | |
} | |
struct none_t {}; | |
constexpr none_t none{}; | |
template<class T>class optional | |
{ | |
union inside_t | |
{ | |
T value; | |
none_t ignore; | |
constexpr inside_t(T const& v) :value(v) {} | |
constexpr inside_t(T&& v) : value(std::move(v)) {} | |
constexpr inside_t(none_t) : ignore(none) {} | |
constexpr inside_t() : ignore(none) {} | |
constexpr inside_t(inside_t const&) = default; | |
inside_t(inside_t&&) = default; | |
inside_t& operator=(inside_t const&) = default; | |
inside_t& operator=(inside_t&&) = default; | |
~inside_t() = default; | |
}; | |
inside_t inside; | |
bool flag; | |
public: | |
void swap(optional&& v) | |
{ | |
std::swap(this->inside, v.inside); | |
std::swap(this->flag, v.flag); | |
} | |
void reset() | |
{ | |
if (flag) | |
{ | |
inside.value.~T(); | |
inside.ignore = none; | |
flag = false; | |
} | |
} | |
constexpr optional(T const& v) :inside(v), flag(true) {} | |
constexpr optional(T&& v) : inside(std::move(v)), flag(true) {} | |
constexpr optional(none_t) : inside(), flag(false) {} | |
constexpr optional() : inside(), flag(false) {} | |
constexpr optional(optional const& v) : inside(v.inside), flag(v.flag) {} | |
optional(optional&& v) : optional() | |
{ | |
swap(std::move(v)); | |
} | |
optional& operator=(optional const& v) | |
{ | |
this->inside = v.inside; | |
this->flag = v.flag; | |
return *this; | |
} | |
optional& operator=(optional&& v) | |
{ | |
swap(std::move(v)); | |
v.reset(); | |
return *this; | |
} | |
optional& operator=(T const& v) | |
{ | |
reset(); | |
inside.value = v; | |
flag = true; | |
return *this; | |
} | |
optional& operator=(T&& v) | |
{ | |
reset(); | |
inside.value = std::move(v); | |
flag = true; | |
return *this; | |
} | |
optional& operator=(none_t) | |
{ | |
reset(); | |
return *this; | |
} | |
constexpr operator bool()const | |
{ | |
return flag; | |
} | |
constexpr T const& operator*()const | |
{ | |
return flag ? inside.value : throw std::domain_error("optional error: dont have value"); | |
} | |
}; | |
template<class T>constexpr optional<typename std::remove_reference<typename std::remove_const<T>::type>::type>make_optional(T&& v) | |
{ | |
return optional<std::remove_reference_t<std::remove_const_t<T>>>(std::forward<T>(v)); | |
} | |
namespace detail | |
{ | |
template<class>struct apply_tuple_t; | |
template<std::size_t... Is>struct apply_tuple_t<std::index_sequence<Is...>> | |
{ | |
template<class Func, class Tuple>static decltype(auto) run(Func func, Tuple const& t) | |
{ | |
return func(std::get<Is>(t)...); | |
} | |
}; | |
} | |
template<class Func, class... Args>decltype(auto) apply_tuple(Func func, std::tuple<Args...>const& vec) | |
{ | |
return detail::apply_tuple_t<std::make_index_sequence<sizeof...(Args)>>::run(func, vec); | |
} | |
template<class T, std::size_t I>constexpr T const& front(T const(&ar)[I]) | |
{ | |
return ar[0]; | |
} | |
template<class Range>auto front(Range const& vec)->decltype(vec[0]) const& | |
{ | |
return vec[0]; | |
} | |
template<class Range>auto front(Range const& vec)->typename std::enable_if< | |
!std::is_same<typename std::iterator_traits<decltype(vec.begin())>::iterator_category,std::random_access_iterator_tag>::value, | |
decltype(vec.front()) const&>::type | |
{ | |
return vec.front(); | |
} | |
template<class T, std::size_t I>constexpr T const& back(T const(&ar)[I]) | |
{ | |
return ar[I - 1]; | |
} | |
template<class Range>auto back(Range const& vec)->decltype(vec[0]) const& | |
{ | |
return vec[vec.size() - 1]; | |
} | |
template<class Range>auto back(Range const& vec)->typename std::enable_if< | |
!std::is_same<typename std::iterator_traits<decltype(vec.begin())>::iterator_category, std::random_access_iterator_tag>::value, | |
decltype(vec.front()) const&>::type | |
{ | |
return vec.back(); | |
} | |
class tribool | |
{ | |
char flag; | |
public: | |
tribool() = default; | |
tribool(tribool&&) = default; | |
tribool(tribool const&) = default; | |
tribool& operator=(tribool&&) = default; | |
tribool& operator=(tribool const&) = default; | |
~tribool() = default; | |
constexpr tribool(none_t) :tribool() {} | |
constexpr tribool(bool f) : flag(0b10 + f) {} | |
constexpr bool is_defined()const | |
{ | |
return static_cast<bool>(flag & 0b10); | |
} | |
constexpr bool is_true()const | |
{ | |
return is_defined() && static_cast<bool>(flag & 0b01); | |
} | |
constexpr bool is_false()const | |
{ | |
return is_defined() && static_cast<bool>(flag ^ 0b11); | |
} | |
}; | |
constexpr bool operator==(tribool b, none_t) | |
{ | |
return !b.is_defined(); | |
} | |
constexpr bool operator==(none_t,tribool b) | |
{ | |
return !b.is_defined(); | |
} | |
constexpr bool operator!=(tribool b, none_t) | |
{ | |
return b.is_defined(); | |
} | |
constexpr bool operator!=(none_t, tribool b) | |
{ | |
return b.is_defined(); | |
} | |
constexpr bool operator==(tribool b, bool f) | |
{ | |
return f ? b.is_true() : b.is_false(); | |
} | |
constexpr bool operator==(bool f,tribool b) | |
{ | |
return f ? b.is_true() : b.is_false(); | |
} | |
constexpr bool operator!=(tribool b, bool f) | |
{ | |
return !(b == f); | |
} | |
constexpr bool operator!=(bool f, tribool b) | |
{ | |
return !(b == f); | |
} | |
constexpr none_t undefined{}; | |
template<class T>using point = std::pair<T, T>; | |
typedef long long int int64; | |
template<class Func>struct scope_exit_t | |
{ | |
Func func; | |
scope_exit_t(Func f) :func(f) {} | |
scope_exit_t(scope_exit_t &&) = delete; | |
scope_exit_t(scope_exit_t const&) = delete; | |
scope_exit_t& operator=(scope_exit_t &&) = delete; | |
scope_exit_t& operator=(scope_exit_t const&) = delete; | |
~scope_exit_t() | |
{ | |
func(); | |
} | |
}; | |
template<class Func>scope_exit_t<Func> scope_exit(Func func) | |
{ | |
return scope_exit_t<Func>(func); | |
} | |
} | |
namespace container | |
{ | |
template<class Type>class dual_array | |
{ | |
std::vector<Type> vec; | |
int x_; | |
public: | |
dual_array(std::size_t x_size, std::size_t y_size) :vec(x_size*y_size), x_(x_size) {} | |
dual_array(dual_array const&) = default; | |
dual_array(dual_array&&) = default; | |
dual_array& operator=(dual_array const&) = default; | |
dual_array& operator=(dual_array&&) = default; | |
auto begin() | |
{ | |
return std::begin(vec); | |
} | |
auto begin()const | |
{ | |
return std::begin(vec); | |
} | |
auto end() | |
{ | |
return std::end(vec); | |
} | |
auto end()const | |
{ | |
return std::end(vec); | |
} | |
Type& operator()(int x, int y) | |
{ | |
return vec[x + y*x_]; | |
} | |
Type const& operator()(int x, int y)const | |
{ | |
return vec[x + y*x_]; | |
} | |
std::size_t size()const | |
{ | |
return vec.size(); | |
} | |
std::size_t x_size()const | |
{ | |
return x_; | |
} | |
std::size_t y_size()const | |
{ | |
return vec.size() / x_; | |
} | |
}; | |
template<class Type, std::size_t Max>class value_tank | |
{ | |
std::array<utility::optional<Type>, Max> value_ = {}; | |
std::size_t size_ = 0; | |
public: | |
value_tank() = default; | |
value_tank(value_tank const&) = default; | |
value_tank(value_tank&&) = default; | |
value_tank& operator=(value_tank const&) = default; | |
value_tank& operator=(value_tank&&) = default; | |
~value_tank() = default; | |
std::size_t size()const | |
{ | |
return size_; | |
} | |
struct iterator :std::iterator<std::input_iterator_tag, Type> | |
{ | |
utility::optional<Type> const* ptr_; | |
iterator(utility::optional<Type> const*ptr) :ptr_(ptr){} | |
iterator(iterator const&) = default; | |
iterator(iterator&&) = default; | |
iterator& operator=(iterator const&) = default; | |
iterator& operator=(iterator&&) = default; | |
~iterator() = default; | |
Type const& operator*()const | |
{ | |
return **ptr_; | |
} | |
iterator& operator++() | |
{ | |
++ptr_; | |
return *this; | |
} | |
iterator operator++(int) | |
{ | |
auto ret = *this; | |
++ptr_; | |
return ret; | |
} | |
bool operator==(iterator const& lhs)const | |
{ | |
return ptr_ == lhs.ptr_; | |
} | |
bool operator!=(iterator const& lhs)const | |
{ | |
return ptr_ != lhs.ptr_; | |
} | |
}; | |
iterator begin()const | |
{ | |
return iterator(&value_[0]); | |
} | |
iterator end()const | |
{ | |
return iterator(&value_[size_]); | |
} | |
void push_back(Type&& v) | |
{ | |
if (size_ < Max) | |
{ | |
value_[size_] = std::move(v); | |
++size_; | |
} | |
} | |
void push_back(Type const& v) | |
{ | |
if (size_ < Max) | |
{ | |
value_[size_] = v; | |
++size_; | |
} | |
} | |
Type const& operator[](std::size_t index)const | |
{ | |
return *(value_[index]); | |
} | |
}; | |
} | |
namespace algorithm | |
{ | |
namespace range | |
{ | |
template<class InputRange, class Pred>bool all_of(InputRange const& ran, Pred pred) | |
{ | |
return std::all_of(std::begin(ran), std::end(ran), pred); | |
} | |
template<class Type, std::size_t I, class Pred>bool all_of(Type const(&ar)[I], Pred pred) | |
{ | |
return std::all_of(std::begin(ar), std::end(ar), pred); | |
} | |
template<class InputRange, class Pred>bool any_of(InputRange const& ran, Pred pred) | |
{ | |
return std::any_of(std::begin(ran), std::end(ran), pred); | |
} | |
template<class Type, std::size_t I, class Pred>bool any_of(Type const(&ar)[I], Pred pred) | |
{ | |
return std::any_of(std::begin(ar), std::end(ar), pred); | |
} | |
template<class InputRange, class Pred>std::size_t count_if(InputRange const& ran, Pred pred) | |
{ | |
return std::count_if(std::begin(ran), std::end(ran), pred); | |
} | |
template<class Type, std::size_t I, class Pred>std::size_t count_if(Type const(&ar), Pred pred) | |
{ | |
return std::count_if(std::begin(ar), std::end(ar), pred); | |
} | |
template<class RandomRange, class Comp>void sort(RandomRange& ran, Comp comp) | |
{ | |
return std::sort(std::begin(ran), std::end(ran), comp); | |
} | |
template<class Type, std::size_t I, class Comp>void sort(Type(&ar)[I], Comp comp) | |
{ | |
return std::sort(std::begin(ar), std::end(ar), comp); | |
} | |
template<class RandomRange>void sort(RandomRange& ran) | |
{ | |
return std::sort(std::begin(ran), std::end(ran)); | |
} | |
template<class Type, std::size_t I>void sort(Type(&ar)[I]) | |
{ | |
return std::sort(std::begin(ar), std::end(ar)); | |
} | |
template<class RandomRange, class Comp>void stable_sort(RandomRange& ran, Comp comp) | |
{ | |
return std::stable_sort(std::begin(ran), std::end(ran), comp); | |
} | |
template<class Type, std::size_t I, class Comp>void stable_sort(Type(&ar)[I], Comp comp) | |
{ | |
return std::stable_sort(std::begin(ar), std::end(ar), comp); | |
} | |
template<class RandomRange>void stable_sort(RandomRange& ran) | |
{ | |
return std::stable_sort(std::begin(ran), std::end(ran)); | |
} | |
template<class Type, std::size_t I>void stable_sort(Type(&ar)[I]) | |
{ | |
return std::stable_sort(std::begin(ar), std::end(ar)); | |
} | |
template<class InputRange>std::size_t unique_count(InputRange const& range) | |
{ | |
std::vector<char> flag; | |
std::size_t count{}; | |
for (auto end = std::begin(range);end != std::end(range);++end) | |
{ | |
auto fla = std::begin(flag); | |
for (auto beg = std::begin(range);beg != end;++beg) | |
{ | |
if (!*fla) | |
continue; | |
if (*beg == *end) | |
{ | |
flag.push_back(false); | |
goto next; | |
} | |
} | |
flag.push_back(true); | |
++count; | |
next:; | |
} | |
return count; | |
} | |
template<class InputRange>auto max(InputRange const& range) | |
{ | |
auto ret = *std::begin(range); | |
for (auto const& v : range) | |
{ | |
ret = std::max(ret, v); | |
} | |
return ret; | |
} | |
template<class InputRange>auto min(InputRange const& range) | |
{ | |
auto ret = *std::begin(range); | |
for (auto const& v : range) | |
{ | |
ret = std::min(ret, v); | |
} | |
return ret; | |
} | |
template<class InputRange, class Pred>auto find(InputRange const& range,Pred pred) | |
->utility::optional<decltype(*std::begin(range))> | |
{ | |
for (auto const& v : range) | |
{ | |
if (pred(v)) | |
return v; | |
} | |
return utility::none; | |
} | |
} | |
namespace dual_range | |
{ | |
namespace detail | |
{ | |
template<class Iterator,class Pred>struct dual_range_adapter | |
{ | |
Iterator ite; | |
Pred pred; | |
template<class Value>decltype(auto) operator()(Value& now) | |
{ | |
return pred(*(ite++), now); | |
} | |
}; | |
template<class Iterator, class Pred>dual_range_adapter<Iterator, Pred> | |
make_dual_range_adapter(Iterator first, Pred pred) | |
{ | |
return dual_range_adapter<Iterator, Pred>{first, pred}; | |
} | |
} | |
template<class Range, class Pred>void for_each(Range& ran, Pred pred) | |
{ | |
auto ite = std::begin(ran); | |
auto last = std::end(ran); | |
if (ite == last)return; | |
std::for_each(std::next(ite), last, detail::make_dual_range_adapter(ite, pred)); | |
} | |
template<class Type, std::size_t I, class Pred>void for_each(Type(&ran)[I], Pred pred) | |
{ | |
auto ite = std::begin(ran); | |
auto last = std::end(ran); | |
if (ite == last)return; | |
std::for_each(std::next(ite), last, detail::make_dual_range_adapter(ite, pred)); | |
} | |
template<class Range, class Pred>auto category_range(Range& ran, Pred pred) | |
{ | |
auto ite = std::begin(ran); | |
auto last = std::end(ran); | |
std::vector<utility::iterator_range<decltype(ite)>> ret{}; | |
if (ite == last) | |
return ret; | |
auto pre = ite; | |
auto fir = pre; | |
++ite; | |
for (;ite != last;[&] {pre = ite++;}()) | |
{ | |
if (pred(*pre, *ite)) | |
{ | |
ret.push_back(utility::make_iterator_range(fir, ite)); | |
fir = ite; | |
} | |
} | |
ret.push_back(utility::make_iterator_range(fir, ite)); | |
return ret; | |
} | |
template<class Type, std::size_t I, class Pred>auto category_range(Type(&ran)[I], Pred pred) | |
{ | |
auto ite = std::begin(ran); | |
auto last = std::end(ran); | |
std::vector<utility::iterator_range<decltype(ite)>> ret{}; | |
if (ite == last) | |
return ret; | |
auto pre = ite; | |
auto fir = pre; | |
++ite; | |
for (;ite != last;[&] {pre = ite++;}()) | |
{ | |
if (pred(*pre, *ite)) | |
{ | |
ret.push_back(utility::make_iterator_range(fir, ite)); | |
fir = ite; | |
} | |
} | |
ret.push_back(fir, ite); | |
return ret; | |
} | |
template<class Range, class Pred>std::size_t count_if(Range& ran, Pred pred) | |
{ | |
auto first = std::begin(ran); | |
auto last = std::end(ran); | |
if (first == last)return 0u; | |
return std::count_if(std::next(first), last, detail::make_dual_range_adapter(first, pred)); | |
} | |
template<class Type, std::size_t I, class Pred>std::size_t count_if(Type(&ran)[I], Pred pred) | |
{ | |
auto first = std::begin(ran); | |
auto last = std::end(ran); | |
if (first == last)return 0u; | |
return std::count_if(std::next(first), last, detail::make_dual_range_adapter(first, pred)); | |
} | |
} | |
namespace other | |
{ | |
namespace detail | |
{ | |
template<class Argument, class Next>struct breadth_first_search; | |
template<class Next,class... Args>struct breadth_first_search<std::tuple<Args...>, Next> | |
{ | |
static auto run(Args... first,Next next) | |
{ | |
std::vector<std::tuple<Args...>> states = { std::make_tuple(first...) }; | |
states.reserve(1000); | |
std::function<void(Args...)> emplace_back = [&states = states](Args... args) | |
{ | |
states.emplace_back(args...); | |
}; | |
auto next_func = [&nex = next, &emplace_back=emplace_back](Args... args) | |
{ | |
return nex(args..., emplace_back); | |
}; | |
int checked = 0; | |
for (int _ = 1;;++_) | |
{ | |
int target = states.size(); | |
for (int i = checked;i < target;++i) | |
{ | |
if (utility::apply_tuple(next_func, states[i])) | |
return _; | |
} | |
checked = target; | |
} | |
} | |
}; | |
} | |
template<class Next, class... Args>auto breadth_first_search(Next next, Args... first)//Next == std::function<bool(Args..., std::function<void(Args...)> const&)> | |
{ | |
return detail::breadth_first_search<std::tuple<Args...>, Next>::run(first..., next); | |
} | |
template<class... Args>struct dijkstra_argorithm_t | |
{ | |
template<class Next>std::size_t operator()(Args... start, Args... target, Next next)//Next == std::function<void(Args..., std::function<void(Args..., std::size_t)> const&)> | |
{ | |
auto end = std::make_tuple(target...); | |
std::vector<std::pair<std::tuple<Args...>, std::size_t>> confirmed = { std::make_pair(std::make_tuple(start...),0) }; | |
std::list<std::pair<std::tuple<Args...>, std::size_t>> candidate; | |
confirmed.reserve(1000); | |
std::size_t from = 0; | |
std::function<void(Args..., std::size_t)> emplace_back = [&candidate, &confirmed, &from](Args... args, std::size_t size) | |
{ | |
auto t = std::make_tuple(args...); | |
auto ite = std::find_if(std::begin(confirmed), std::end(confirmed), [&t = t](auto const& p){return p.first == t;}); | |
if (ite != std::end(confirmed))return; | |
auto ite2 = std::find_if(std::begin(candidate), std::end(candidate), [&t = t](auto const& p){return p.first == t;}); | |
if (ite2 != std::end(candidate)) | |
{ | |
ite2->second = std::min(ite2->second, from + size); | |
} | |
else | |
{ | |
candidate.emplace_back(t, from + size); | |
} | |
}; | |
auto next_func = [&nex = next, &emplace_back = emplace_back](Args... args) | |
{ | |
return nex(args..., emplace_back); | |
}; | |
while (true) | |
{ | |
from = confirmed[utility::size(confirmed) - 1].second; | |
utility::apply_tuple(next_func, confirmed[utility::size(confirmed) - 1].first); | |
auto ite = candidate.begin(); | |
for (auto i = candidate.begin();i != candidate.end();++i) | |
{ | |
if (ite->second > i->second) | |
ite = i; | |
} | |
confirmed.push_back(*ite); | |
candidate.erase(ite); | |
if (confirmed[utility::size(confirmed) - 1].first == end) | |
break; | |
} | |
return confirmed[utility::size(confirmed) - 1].second; | |
} | |
}; | |
} | |
} | |
namespace iostream | |
{ | |
template<class Type>Type read() | |
{ | |
Type ret; | |
std::cin >> ret; | |
return ret; | |
} | |
template<class TypeA, class TypeB>std::pair<TypeA, TypeB> twin_read() | |
{ | |
TypeA a; | |
TypeB b; | |
std::cin >> a >> b; | |
return std::make_tuple(a, b); | |
} | |
namespace detail | |
{ | |
template<class T>auto tuple_read() | |
{ | |
return std::make_tuple(iostream::read<T>()); | |
} | |
template<class T,class... Ts>auto tuple_read()->typename std::enable_if<(sizeof...(Ts)>0), std::tuple<T, Ts...>>::type | |
{ | |
T v = iostream::read<T>(); | |
return std::tuple_cat(std::make_tuple(v), tuple_read<Ts...>()); | |
} | |
} | |
template<class... Ts>auto tuple_read() | |
{ | |
return detail::tuple_read<Ts...>(); | |
} | |
template<class... Ts>auto vector_read(std::size_t size)-> | |
typename std::enable_if<(sizeof...(Ts)>1), std::vector<std::tuple<Ts...>>>::type | |
{ | |
std::vector<std::tuple<Ts...>> ret; | |
for (std::size_t i = 0;i < size;++i) | |
{ | |
ret.push_back(tuple_read<Ts...>()); | |
} | |
return std::move(ret); | |
} | |
template<class T>auto vector_read(std::size_t size) | |
{ | |
std::vector<T> ret; | |
for (std::size_t i = 0;i < size;++i) | |
{ | |
ret.push_back(read<T>()); | |
} | |
return std::move(ret); | |
} | |
} | |
namespace adaptor | |
{ | |
namespace classes | |
{ | |
template<class Iterator, class Pred>struct filter_t | |
{ | |
Iterator first; | |
Iterator last; | |
Pred pred; | |
struct iterator :std::iterator< | |
std::forward_iterator_tag, | |
typename std::iterator_traits<Iterator>::value_type, | |
typename std::iterator_traits<Iterator>::difference_type, | |
typename std::iterator_traits<Iterator>::pointer, | |
typename std::iterator_traits<Iterator>::reference> | |
{ | |
Iterator ite; | |
Iterator last; | |
Pred pred; | |
iterator(Iterator i, Iterator las, Pred p) :ite(i), last(las), pred(p) {} | |
iterator(iterator const&) = default; | |
iterator(iterator&&) = default; | |
iterator& operator=(iterator const&) = default; | |
iterator& operator=(iterator&&) = default; | |
~iterator() = default; | |
iterator& operator++() | |
{ | |
++ite; | |
for (;ite != last;++ite) | |
{ | |
if (pred(*ite)) | |
return *this; | |
} | |
return *this; | |
} | |
iterator operator++(int) | |
{ | |
auto ret = *this; | |
++ite; | |
for (;ite != last;++ite) | |
{ | |
if (pred(*ite)) | |
return ret; | |
} | |
return ret; | |
} | |
typename std::iterator_traits<Iterator>::value_type const& operator*() | |
{ | |
return *ite; | |
} | |
typename std::iterator_traits<Iterator>::value_type const& operator*()const | |
{ | |
return *ite; | |
} | |
bool operator==(iterator const& rhs)const | |
{ | |
return rhs.ite == this->ite; | |
} | |
bool operator!=(iterator const& rhs)const | |
{ | |
return rhs.ite != this->ite; | |
} | |
}; | |
iterator begin()const | |
{ | |
return iterator(first, last, pred); | |
} | |
iterator end()const | |
{ | |
return iterator(last, last, pred); | |
} | |
filter_t(Iterator fir, Iterator las, Pred p) :first(fir), last(las), pred(p) {} | |
filter_t(filter_t const&) = default; | |
filter_t(filter_t&&) = default; | |
filter_t& operator=(filter_t const&) = default; | |
filter_t& operator=(filter_t&&) = default; | |
~filter_t() = default; | |
}; | |
struct filter_adaptor_t | |
{ | |
template<class Pred>struct filter_adaptor | |
{ | |
Pred pred; | |
}; | |
template<class Pred>filter_adaptor<Pred> operator()(Pred pred)const | |
{ | |
return filter_adaptor<Pred>{pred}; | |
} | |
}; | |
template<class Range, class Pred>auto operator|(Range const& range, filter_adaptor_t::filter_adaptor<Pred> filter) | |
->filter_t<decltype(range.begin()), Pred> | |
{ | |
return filter_t<decltype(range.begin()), Pred>(range.begin(), range.end(), filter.pred); | |
} | |
template<class Iterator, class Func>struct transport_t | |
{ | |
Iterator first; | |
Iterator last; | |
Func func; | |
struct iterator :std::iterator< | |
std::forward_iterator_tag, | |
typename std::iterator_traits<Iterator>::value_type, | |
typename std::iterator_traits<Iterator>::difference_type, | |
typename std::iterator_traits<Iterator>::pointer, | |
typename std::iterator_traits<Iterator>::reference> | |
{ | |
Iterator ite; | |
Iterator last; | |
Func func; | |
iterator(Iterator i, Iterator las, Func p) :ite(i), last(las), func(p) {} | |
iterator(iterator const&) = default; | |
iterator(iterator&&) = default; | |
iterator& operator=(iterator const&) = default; | |
iterator& operator=(iterator&&) = default; | |
~iterator() = default; | |
iterator& operator++() | |
{ | |
++ite; | |
return *this; | |
} | |
iterator operator++(int) | |
{ | |
auto ret = *this; | |
++ite; | |
return ret; | |
} | |
auto operator*()const | |
{ | |
return func(*ite); | |
} | |
bool operator==(iterator const& rhs)const | |
{ | |
return rhs.ite == this->ite; | |
} | |
bool operator!=(iterator const& rhs)const | |
{ | |
return rhs.ite != this->ite; | |
} | |
}; | |
iterator begin()const | |
{ | |
return iterator(first, last, func); | |
} | |
iterator end()const | |
{ | |
return iterator(last, last, func); | |
} | |
transport_t(Iterator fir, Iterator las, Func p) :first(fir), last(las), func(p) {} | |
transport_t(transport_t const&) = default; | |
transport_t(transport_t&&) = default; | |
transport_t& operator=(transport_t const&) = default; | |
transport_t& operator=(transport_t&&) = default; | |
~transport_t() = default; | |
}; | |
struct transport_adaptor_t | |
{ | |
template<class Func>struct transport_adaptor | |
{ | |
Func func; | |
}; | |
template<class Func>transport_adaptor<Func> operator()(Func const& func)const | |
{ | |
return transport_adaptor<Func>{func}; | |
} | |
}; | |
template<class Range, class Func>auto operator|(Range const& range,transport_adaptor_t::transport_adaptor<Func> adaptor) | |
->transport_t<decltype(range.begin()), Func> | |
{ | |
return transport_t<decltype(range.begin()), Func>(range.begin(), range.end(), adaptor.func); | |
} | |
template<class Iterator>struct indexes_t | |
{ | |
Iterator first; | |
Iterator last; | |
struct iterator :std::iterator< | |
std::input_iterator_tag, | |
std::pair<typename std::iterator_traits<Iterator>::value_type, std::size_t>, | |
typename std::iterator_traits<Iterator>::difference_type, | |
typename std::iterator_traits<Iterator>::pointer, | |
typename std::iterator_traits<Iterator>::reference> | |
{ | |
Iterator ite; | |
std::size_t count; | |
iterator(Iterator i) :ite(i), count(0u) {} | |
iterator(iterator const&) = default; | |
iterator(iterator&&) = default; | |
iterator& operator=(iterator const&) = default; | |
iterator& operator=(iterator&&) = default; | |
~iterator() = default; | |
iterator& operator++() | |
{ | |
++ite; | |
++count; | |
return *this; | |
} | |
iterator operator++(int) | |
{ | |
auto ret = *this; | |
++ite; | |
++count; | |
return ret; | |
} | |
std::pair<typename std::iterator_traits<Iterator>::value_type, std::size_t>operator*()const | |
{ | |
return std::make_pair(*ite, count); | |
} | |
bool operator==(iterator const& rhs)const | |
{ | |
return rhs.ite == this->ite; | |
} | |
bool operator!=(iterator const& rhs)const | |
{ | |
return rhs.ite != this->ite; | |
} | |
}; | |
iterator begin()const | |
{ | |
return iterator(first); | |
} | |
iterator end()const | |
{ | |
return iterator(last); | |
} | |
}; | |
struct indexes_adaptor | |
{ | |
}; | |
template<class Range>auto operator|(Range const& range, indexes_adaptor) | |
->indexes_t<decltype(range.begin())> | |
{ | |
return indexes_t<decltype(range.begin())>{range.begin(), range.end()}; | |
} | |
struct to_vector_adaptor | |
{ | |
}; | |
template<class Range>auto operator|(Range const& range, to_vector_adaptor) | |
->std::vector<typename std::iterator_traits<decltype(range.begin())>::value_type> | |
{ | |
std::vector<typename std::iterator_traits<decltype(std::begin(range))>::value_type> ret{ std::begin(range),std::end(range) }; | |
return ret; | |
} | |
struct skip_adaptor | |
{ | |
struct skip_adaptor_t | |
{ | |
int v; | |
}; | |
skip_adaptor_t operator()(int v)const | |
{ | |
return skip_adaptor_t{ v }; | |
} | |
}; | |
template<class Range>auto operator|(Range const& range, skip_adaptor::skip_adaptor_t adaptor) | |
->utility::iterator_range<decltype(range.begin())> | |
{ | |
return utility::make_iterator_range(std::next(std::begin(range), adaptor.v), std::end(range)); | |
} | |
template<class IteratorA, class IteratorB>struct dual_t | |
{ | |
struct iterator:std::iterator<std::forward_iterator_tag,std::pair< | |
typename std::iterator_traits<IteratorA>::value_type, | |
typename std::iterator_traits<IteratorB>::value_type>> | |
{ | |
IteratorA itea; | |
IteratorB iteb; | |
iterator(IteratorA a, IteratorB b) :itea(a), iteb(b) {} | |
iterator(iterator const&) = default; | |
iterator(iterator&&) = default; | |
iterator& operator=(iterator const&) = default; | |
iterator& operator=(iterator&&) = default; | |
~iterator() = default; | |
bool operator!=(iterator const& rhs)const | |
{ | |
return itea != rhs.itea&&iteb != rhs.iteb; | |
} | |
auto operator*()const | |
{ | |
return std::make_pair(*itea, *iteb); | |
} | |
iterator& operator++() | |
{ | |
++itea; | |
++iteb; | |
return *this; | |
} | |
}; | |
IteratorA firsta; | |
IteratorB firstb; | |
IteratorA lasta; | |
IteratorB lastb; | |
iterator begin()const | |
{ | |
return iterator(firsta, firstb); | |
} | |
iterator end()const | |
{ | |
return iterator(lasta, lastb); | |
} | |
}; | |
struct dual_adaptor_t | |
{ | |
template<class Iterator>struct adaptor | |
{ | |
Iterator first; | |
Iterator last; | |
}; | |
template<class Range>auto operator()(Range const& range)const ->adaptor<decltype(std::begin(range))> | |
{ | |
return adaptor<decltype(std::begin(range))>{std::begin(range), std::end(range)}; | |
} | |
}; | |
template<class Range, class Iterator>auto operator|(Range const& lhs, dual_adaptor_t::adaptor<Iterator>const& rhs) | |
{ | |
return dual_t<decltype(std::begin(lhs)), Iterator>{std::begin(lhs), rhs.first, std::end(lhs), rhs.last}; | |
} | |
} | |
template<class Range, class Pred>auto filtered(Range const& range, Pred pred) | |
->classes::filter_t<decltype(range.begin()), Pred> | |
{ | |
return classes::filter_t<decltype(range.begin()), Pred>(range.begin(), range.end(), pred); | |
} | |
constexpr classes::filter_adaptor_t filter{}; | |
template<class Range, class Func>auto transported(Range const& range, Func func) | |
->classes::transport_t<decltype(range.begin()), Func> | |
{ | |
return classes::transport_t<decltype(range.begin()), Func>(range.begin(), range.end(), func); | |
} | |
constexpr classes::transport_adaptor_t transport{}; | |
template<class Range>auto indexed(Range const& range) | |
->classes::indexes_t<decltype(range.begin())> | |
{ | |
return classes::indexes_t<decltype(range.begin())>{range.begin(), range.end()}; | |
} | |
constexpr classes::indexes_adaptor indexes{}; | |
template<class Range>auto vectored(Range const& range) | |
->std::vector<typename std::iterator_traits<decltype(range.begin())>::value_type> | |
{ | |
std::vector<typename std::iterator_traits<decltype(range.begin())>::value_type> ret{ range.begin().range.end() }; | |
return ret; | |
} | |
constexpr classes::to_vector_adaptor to_vector{}; | |
template<class Range>auto range_skip(Range const& range, int v) | |
->utility::iterator_range<decltype(range.begin())> | |
{ | |
return utility::make_iterator_range(std::next(range.begin(), v), range.end()); | |
} | |
constexpr classes::skip_adaptor skip{}; | |
template<class RangeA, class RangeB>auto dual_range(RangeA const& range_a, RangeB const& range_b) | |
{ | |
return classes::dual_t<decltype(std::begin(range_a)), decltype(std::begin(range_b))> | |
{ | |
std::begin(range_a),std::begin(range_b),std::end(range_a),std::end(range_b) | |
}; | |
} | |
constexpr classes::dual_adaptor_t dual{}; | |
} | |
namespace math | |
{ | |
template<class T>T pow(T p, int n) | |
{ | |
return n == 0 ? 1 : n == 1 ? p : n == 2 ? p*p : n % 2 == 0 ? pow(pow(p, n / 2), 2) : pow(pow(p, n / 2), 2)*p; | |
} | |
int log(long long int p, int n) | |
{ | |
utility::int64 t = n; | |
for (int i = 0;;++i) | |
{ | |
if (t > p) | |
return i; | |
t *= n; | |
} | |
} | |
constexpr double pi = 3.141592653589793; | |
namespace detail | |
{ | |
int gcd(int larger, int less) | |
{ | |
return less == 0 ? larger : gcd(less, larger%less); | |
} | |
} | |
int gcd(int lhs, int rhs) | |
{ | |
return lhs < rhs ? detail::gcd(rhs, lhs) : detail::gcd(lhs, rhs); | |
} | |
class polynomial | |
{ | |
std::vector<std::complex<double>> value; | |
void swap(polynomial&& p) | |
{ | |
std::swap(value, p.value); | |
} | |
public: | |
polynomial() :value{ 0.0 } {} | |
polynomial(polynomial const&) = default; | |
polynomial(std::vector<std::complex<double>>&& vec) :value(std::move(vec)) {} | |
polynomial(polynomial&& p) :polynomial() | |
{ | |
swap(std::move(p)); | |
} | |
polynomial(std::initializer_list<std::complex<double>> lis) :value(lis) {} | |
polynomial& operator=(polynomial const&) = default; | |
polynomial& operator=(polynomial&& p) | |
{ | |
value = std::vector<std::complex<double>>{ 0.0 }; | |
swap(std::move(p)); | |
return *this; | |
} | |
~polynomial() = default; | |
std::complex<double> operator[](std::size_t deg)const | |
{ | |
return deg >= value.size() ? 0.0 : value[deg]; | |
} | |
std::size_t degree()const | |
{ | |
return value.size() - 1; | |
} | |
void strict_degree_set() | |
{ | |
int N = degree(); | |
for (;N > 0;--N) | |
{ | |
if (value[N] != 0.0) | |
break; | |
} | |
value.resize(N + 1); | |
} | |
friend polynomial fourier_transform(polynomial const& p, std::size_t N) | |
{ | |
std::vector<std::complex<double>> vec = p.value; | |
vec.resize(N); | |
std::size_t i = 0; | |
for (std::size_t j = 1;j < N - 1;++j) | |
{ | |
for (std::size_t k = N >> 1;k > (i ^= k);k >>= 1); | |
if (j < i) | |
{ | |
std::swap(vec[i], vec[j]); | |
} | |
} | |
std::size_t m; | |
for (std::size_t mh = 1;(m = mh << 1) <= N;mh = m) | |
{ | |
std::size_t irev = 0; | |
for (std::size_t i = 0;i < N;i += m) | |
{ | |
std::complex<double> c(std::cos(2 * pi*irev / N), std::sin(2 * pi*irev / N)); | |
std::size_t k; | |
for (k = N >> 2;k > (irev ^= k);k >>= 1); | |
for (std::size_t j = i;j < mh + i;++j) | |
{ | |
k = j + mh; | |
auto x = vec[j] - vec[k]; | |
vec[j] += vec[k]; | |
vec[k] = c*x; | |
} | |
} | |
} | |
return polynomial(std::move(vec)); | |
} | |
friend polynomial inverse_fourier_transform(polynomial const& p, std::size_t N) | |
{ | |
std::vector<std::complex<double>> vec = p.value; | |
vec.resize(N); | |
std::size_t i = 0; | |
for (std::size_t j = 1;j < N - 1;++j) | |
{ | |
for (std::size_t k = N >> 1;k >(i ^= k);k >>= 1); | |
if (j < i) | |
{ | |
std::swap(vec[i], vec[j]); | |
} | |
} | |
std::size_t m; | |
for (std::size_t mh = 1;(m = mh << 1) <= N;mh = m) | |
{ | |
std::size_t irev = 0; | |
for (std::size_t i = 0;i < N;i += m) | |
{ | |
std::complex<double> c(std::cos(2 * pi*irev / N), -std::sin(2 * pi*irev / N)); | |
std::size_t k; | |
for (k = N >> 2;k >(irev ^= k);k >>= 1); | |
for (std::size_t j = i;j < mh + i;++j) | |
{ | |
k = j + mh; | |
auto x = vec[j] - vec[k]; | |
vec[j] += vec[k]; | |
vec[k] = c*x; | |
} | |
} | |
} | |
for (auto& v : vec) | |
{ | |
v /= N; | |
} | |
return polynomial(std::move(vec)); | |
} | |
friend polynomial operator*(polynomial const& lhs, polynomial const& rhs) | |
{ | |
std::size_t N = 1; | |
while (true) | |
{ | |
N *= 2; | |
if (N > (lhs.degree() + rhs.degree())) | |
break; | |
} | |
auto lhs_ = fourier_transform(lhs, N); | |
auto rhs_ = fourier_transform(rhs, N); | |
std::vector<std::complex<double>> vec; | |
for (std::size_t i = 0;i < N;++i) | |
{ | |
vec.push_back(lhs_[i] * rhs_[i]); | |
} | |
auto ret = inverse_fourier_transform(polynomial(std::move(vec)), N); | |
ret.strict_degree_set(); | |
return ret; | |
} | |
}; | |
int real_integer(std::complex<int> c) | |
{ | |
int v = c.real(); | |
return v + (c.real() - v > 0 / 5); | |
} | |
template<class T>polynomial make_poly(std::vector<T> const& vec) | |
{ | |
auto range = vec | adaptor::transport([](T const& v) {return static_cast<std::complex<double>>(v);}); | |
std::vector<std::complex<double>> ret(std::begin(range), std::end(range)); | |
return polynomial(std::move(ret)); | |
} | |
} | |
namespace string | |
{ | |
namespace detail | |
{ | |
struct substring | |
{ | |
std::string const& str_; | |
std::size_t start_; | |
std::size_t size_; | |
bool operator==(substring const& rhs)const | |
{ | |
if (size_ != rhs.size_) | |
return false; | |
for (std::size_t i = 0;i < size_;++i) | |
{ | |
if (rhs.str_[rhs.start_ + i] != str_[start_ + i]) | |
return false; | |
} | |
return true; | |
} | |
bool operator!=(substring const& rhs)const | |
{ | |
return !(rhs.operator==(*this)); | |
} | |
std::string str()const | |
{ | |
return str_.substr(start_, size_); | |
} | |
}; | |
struct substring_iterator :std::iterator<std::input_iterator_tag, substring> | |
{ | |
std::string const& str_; | |
std::size_t start_; | |
std::size_t size_; | |
substring_iterator(std::string const& str, std::size_t start, std::size_t size) :str_(str), start_(start), size_(size) {} | |
substring_iterator(substring_iterator&&) = default; | |
substring_iterator(substring_iterator const&) = default; | |
substring_iterator& operator=(substring_iterator&&) = default; | |
substring_iterator& operator=(substring_iterator const&) = default; | |
~substring_iterator() = default; | |
substring_iterator& operator++() | |
{ | |
++start_; | |
return *this; | |
} | |
substring_iterator operator++(int) | |
{ | |
auto ret = *this; | |
++start_; | |
return ret; | |
} | |
substring operator*()const | |
{ | |
return substring{ str_,start_,size_ }; | |
} | |
bool operator==(substring_iterator const& rhs)const | |
{ | |
return &str_ == &str_ && | |
start_ == rhs.start_&& | |
size_ == rhs.size_; | |
} | |
bool operator!=(substring_iterator const& rhs)const | |
{ | |
return !rhs.operator==(*this); | |
} | |
}; | |
} | |
class substring_adaptor | |
{ | |
std::string const& str_; | |
std::size_t size_; | |
public: | |
substring_adaptor(std::string const& str, std::size_t size) :str_(str), size_(size) {} | |
substring_adaptor(substring_adaptor&&) = default; | |
substring_adaptor(substring_adaptor const&) = default; | |
substring_adaptor& operator=(substring_adaptor&&) = default; | |
substring_adaptor& operator=(substring_adaptor const&) = default; | |
~substring_adaptor() = default; | |
detail::substring_iterator begin()const | |
{ | |
if (str_.size() < size_) | |
return detail::substring_iterator(str_, 0, 0); | |
return detail::substring_iterator(str_, 0, size_); | |
} | |
detail::substring_iterator end()const | |
{ | |
if (str_.size() < size_) | |
return detail::substring_iterator(str_, 0, 0); | |
return detail::substring_iterator(str_, str_.size() - size_ + 1, size_); | |
} | |
}; | |
} | |
void Main(std::integral_constant<int, 0>); | |
void Main(std::integral_constant<int, 1>); | |
void Main(std::integral_constant<int, 2>); | |
void Main(std::integral_constant<int, 3>); | |
void Main(std::integral_constant<int, 4>); | |
#endif//テンプレートここまで | |
//ここを書き換える | |
constexpr int problem = 0; | |
//ここは書き換えない | |
int main() | |
{ | |
std::cin.sync_with_stdio(false); | |
Main(std::integral_constant<int, problem>{}); | |
} | |
void Main(std::integral_constant<int, 0>) | |
{ | |
} | |
void Main(std::integral_constant<int, 1>) | |
{ | |
} | |
void Main(std::integral_constant<int, 2>) | |
{ | |
} | |
void Main(std::integral_constant<int, 3>) | |
{ | |
} | |
void Main(std::integral_constant<int, 4>) | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment