結果
問題 | No.16 累乗の加算 |
ユーザー | hly1204 |
提出日時 | 2020-09-07 23:56:45 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2 ms / 5,000 ms |
コード長 | 3,932 bytes |
コンパイル時間 | 1,010 ms |
コンパイル使用メモリ | 115,792 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-05-07 00:21:13 |
合計ジャッジ時間 | 1,817 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 1 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 1 ms
5,376 KB |
testcase_13 | AC | 2 ms
5,376 KB |
ソースコード
#ifndef LOCAL #define NDEBUG #endif #include <algorithm> #include <cassert> #include <cstring> #include <functional> #include <initializer_list> #include <iostream> #include <memory> #include <random> #include <vector> template <std::uint32_t P> struct MontgomeryModInt32 { public: using i32 = std::int32_t; using u32 = std::uint32_t; using i64 = std::int64_t; using u64 = std::uint64_t; using mont = MontgomeryModInt32; private: u32 v; static constexpr u32 get_r() { u32 iv = P; for (u32 i = 0; i != 4; ++i) iv *= 2U - P * iv; return -iv; } static constexpr u32 r = get_r(), r2 = -u64(P) % P; static_assert((P & 1) == 1); static_assert(-r * P == 1); static_assert(P < (1 << 30)); static constexpr u32 pow_mod(u32 x, u64 y) { u32 res = 1; for (; y != 0; y >>= 1, x = u64(x) * x % P) if (y & 1) res = u64(res) * x % P; return res; } public: static constexpr u32 get_pr() { u32 tmp[32] = {}, cnt = 0; const u64 phi = P - 1; u64 m = phi; for (u64 i = 2; i * i <= m; ++i) if (m % i == 0) { tmp[cnt++] = i; while (m % i == 0) m /= i; } if (m != 1) tmp[cnt++] = m; for (u64 res = 2; res != P; ++res) { bool flag = true; for (u32 i = 0; i != cnt && flag; ++i) flag &= pow_mod(res, phi / tmp[i]) != 1; if (flag) return res; } return 0; } MontgomeryModInt32() = default; ~MontgomeryModInt32() = default; constexpr MontgomeryModInt32(u32 v) : v(reduce(u64(v) * r2)) {} constexpr MontgomeryModInt32(const mont &rhs) : v(rhs.v) {} static constexpr u32 reduce(u64 x) { return x + (u64(u32(x) * r) * P) >> 32; } static constexpr u32 norm(u32 x) { return x - (P & -(x >= P)); } constexpr u32 get() const { u32 res = reduce(v) - P; return res + (P & -(res >> 31)); } explicit constexpr operator u32() const { return get(); } explicit constexpr operator i32() const { return i32(get()); } constexpr mont &operator=(const mont &rhs) { return v = rhs.v, *this; } constexpr mont operator-() const { mont res; return res.v = (P << 1 & -(v != 0)) - v, res; } constexpr mont inv() const { return pow(-1); } constexpr mont &operator+=(const mont &rhs) { return v += rhs.v - (P << 1), v += P << 1 & -(v >> 31), *this; } constexpr mont &operator-=(const mont &rhs) { return v -= rhs.v, v += P << 1 & -(v >> 31), *this; } constexpr mont &operator*=(const mont &rhs) { return v = reduce(u64(v) * rhs.v), *this; } constexpr mont &operator/=(const mont &rhs) { return this->operator*=(rhs.inv()); } friend mont operator+(const mont &lhs, const mont &rhs) { return mont(lhs) += rhs; } friend mont operator-(const mont &lhs, const mont &rhs) { return mont(lhs) -= rhs; } friend mont operator*(const mont &lhs, const mont &rhs) { return mont(lhs) *= rhs; } friend mont operator/(const mont &lhs, const mont &rhs) { return mont(lhs) /= rhs; } friend bool operator==(const mont &lhs, const mont &rhs) { return norm(lhs.v) == norm(rhs.v); } friend bool operator!=(const mont &lhs, const mont &rhs) { return norm(lhs.v) != norm(rhs.v); } friend std::istream &operator>>(std::istream &is, mont &rhs) { return is >> rhs.v, rhs.v = reduce(u64(rhs.v) * r2), is; } friend std::ostream &operator<<(std::ostream &os, const mont &rhs) { return os << rhs.get(); } constexpr mont pow(i64 y) const { if ((y %= P - 1) < 0) y += P - 1; // phi(P) = P - 1, assume P is a prime number mont res(1), x(*this); for (; y != 0; y >>= 1, x *= x) if (y & 1) res *= x; return res; } }; int main() { #ifdef LOCAL std::freopen("..\\in", "r", stdin), std::freopen("..\\out", "w", stdout); #endif std::ios::sync_with_stdio(false); std::cin.tie(0); int n, m; std::cin >> n >> m; MontgomeryModInt32<1000003> a(n), ans(0); while (m--) { int v; std::cin >> v; ans += a.pow(v); } std::cout << ans; return 0; }