結果
問題 | No.940 ワープ ε=ε=ε=ε=ε=│;p>д<│ |
ユーザー |
![]() |
提出日時 | 2019-12-03 00:48:28 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 52 ms / 5,000 ms |
コード長 | 7,028 bytes |
コンパイル時間 | 799 ms |
コンパイル使用メモリ | 76,672 KB |
実行使用メモリ | 40,740 KB |
最終ジャッジ日時 | 2024-11-28 10:06:26 |
合計ジャッジ時間 | 2,129 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 22 |
ソースコード
//#define NDEBUG#include <algorithm>#include <cstddef>#include <cstdint>#include <iostream>#include <utility>#include <vector>namespace n91 {using i8 = std::int_fast8_t;using i32 = std::int_fast32_t;using i64 = std::int_fast64_t;using u8 = std::uint_fast8_t;using u32 = std::uint_fast32_t;using u64 = std::uint_fast64_t;using isize = std::ptrdiff_t;using usize = std::size_t;struct rep {struct itr {usize i;constexpr itr(const usize i) noexcept : i(i) {}void operator++() noexcept { ++i; }constexpr usize operator*() const noexcept { return i; }constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }};const itr f, l;constexpr rep(const usize f, const usize l) noexcept: f(std::min(f, l)), l(l) {}constexpr auto begin() const noexcept { return f; }constexpr auto end() const noexcept { return l; }};struct revrep {struct itr {usize i;constexpr itr(const usize i) noexcept : i(i) {}void operator++() noexcept { --i; }constexpr usize operator*() const noexcept { return i; }constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }};const itr f, l;constexpr revrep(const usize f, const usize l) noexcept: f(l - 1), l(std::min(f, l) - 1) {}constexpr auto begin() const noexcept { return f; }constexpr auto end() const noexcept { return l; }};template <class T> auto md_vec(const usize n, const T &value) {return std::vector<T>(n, value);}template <class... Args> auto md_vec(const usize n, Args... args) {return std::vector<decltype(md_vec(args...))>(n, md_vec(args...));}template <class T> constexpr T difference(const T &a, const T &b) noexcept {if (a < b) {return b - a;} else {return a - b;}}template <class T> void chmin(T &a, const T &b) noexcept {if (b < a) {a = b;}}template <class T> void chmax(T &a, const T &b) noexcept {if (a < b) {a = b;}}template <class F> class fix_point : private F {public:explicit constexpr fix_point(F &&f) : F(std::forward<F>(f)) {}template <class... Args>constexpr decltype(auto) operator()(Args &&... args) const {return F::operator()(*this, std::forward<Args>(args)...);}};template <class F> constexpr decltype(auto) make_fix(F &&f) {return fix_point<F>(std::forward<F>(f));}template <class T> T scan() {T ret;std::cin >> ret;return ret;}} // namespace n91#include <cstdint>namespace n91 {constexpr std::uint_fast64_t totient(std::uint_fast64_t x) noexcept {using u64 = std::uint_fast64_t;u64 ret = x;for (u64 i = static_cast<u64>(2); i * i <= x; ++i) {if (x % i == static_cast<u64>(0)) {ret -= ret / i;x /= i;while (x % i == static_cast<u64>(0)) {x /= i;}}}if (x != static_cast<u64>(1)) {ret -= ret / x;}return ret;}template <std::uint_fast64_t Modulus,std::uint_fast64_t InverseExp =totient(Modulus) - static_cast<std::uint_fast64_t>(1)>class modint {using u64 = std::uint_fast64_t;static_assert(Modulus < static_cast<u64>(1) << static_cast<u64>(32),"Modulus must be less than 2**32");u64 a;constexpr modint &negate() noexcept {if (a != static_cast<u64>(0)) {a = Modulus - a;}return *this;}public:constexpr modint(const u64 x = static_cast<u64>(0)) noexcept: a(x % Modulus) {}constexpr u64 &value() noexcept { return a; }constexpr const u64 &value() const noexcept { return a; }constexpr modint operator+() const noexcept { return modint(*this); }constexpr modint operator-() const noexcept { return modint(*this).negate(); }constexpr modint operator+(const modint rhs) const noexcept {return modint(*this) += rhs;}constexpr modint operator-(const modint rhs) const noexcept {return modint(*this) -= rhs;}constexpr modint operator*(const modint rhs) const noexcept {return modint(*this) *= rhs;}constexpr modint operator/(const modint rhs) const noexcept {return modint(*this) /= rhs;}constexpr modint &operator+=(const modint rhs) noexcept {a += rhs.a;if (a >= Modulus) {a -= Modulus;}return *this;}constexpr modint &operator-=(const modint rhs) noexcept {if (a < rhs.a) {a += Modulus;}a -= rhs.a;return *this;}constexpr modint &operator*=(const modint rhs) noexcept {a = a * rhs.a % Modulus;return *this;}constexpr modint &operator/=(modint rhs) noexcept {u64 exp = InverseExp;while (exp) {if (exp % static_cast<u64>(2) != static_cast<u64>(0)) {*this *= rhs;}rhs *= rhs;exp /= static_cast<u64>(2);}return *this;}constexpr bool operator==(const modint rhs) const noexcept {return a == rhs.a;}constexpr bool operator!=(const modint rhs) const noexcept {return a != rhs.a;}};template <class T, std::uint_fast64_t v> class modint_constant {public:static constexpr T value = static_cast<T>(v);using value_type = T;};template <class T, std::uint_fast64_t v>constexpr T modint_constant<T, v>::value;} // namespace n91#include <vector>namespace n91 {template <class T> class fact_binom {public:using value_type = T;using container_type = std::vector<value_type>;using size_type = typename container_type::size_type;private:container_type factrial, inv_fact;public:fact_binom() : factrial(), inv_fact() {}explicit fact_binom(const size_type n) : factrial(n + 1), inv_fact(n + 1) {factrial[0] = static_cast<value_type>(1);for (size_type i = 0; i != n; ++i) {factrial[i + 1] = static_cast<value_type>(i + 1) * factrial[i];}inv_fact[n] = static_cast<value_type>(1) / factrial[n];for (size_type i = n; i != 0; --i) {inv_fact[i - 1] = inv_fact[i] * static_cast<value_type>(i);}}value_type operator()(const size_type n, const size_type r) const {return factrial[n] * inv_fact[r] * inv_fact[n - r];}};} // namespace n91#include <algorithm>#include <iostream>#include <utility>namespace n91 {void main_() {/*std::ios::sync_with_stdio(false);std::cin.tie(nullptr);//*/using mint = modint<1000000007>;const usize x = scan<usize>();const usize y = scan<usize>();const usize z = scan<usize>();if (x == 0 && y == 0 && z == 0) {std::cout << 1 << std::endl;return;}const fact_binom<mint> binom((x + y + z + 10) * 2);const auto h = [&](const usize n, const usize r) {return binom(n + r - 1, n);};mint ans = 0;mint coef = 1;const usize s = x + y + z + 1;for (usize k = s; --k != 0;) {ans += coef * h(x, k) * h(y, k) * h(z, k);if ((s - k) % 2 == 0) {coef = coef + coef + binom(s, s - k);} else {coef = coef + coef - binom(s, s - k);}}std::cout << ans.value() << std::endl;}} // namespace n91int main() {n91::main_();return 0;}