結果
問題 | No.2394 部分和乗総和 |
ユーザー | CoCo_Japan_pan |
提出日時 | 2023-08-10 18:28:24 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 137 ms / 2,000 ms |
コード長 | 7,698 bytes |
コンパイル時間 | 6,099 ms |
コンパイル使用メモリ | 219,672 KB |
実行使用メモリ | 6,824 KB |
最終ジャッジ日時 | 2024-11-17 03:12:34 |
合計ジャッジ時間 | 5,806 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,820 KB |
testcase_03 | AC | 2 ms
6,816 KB |
testcase_04 | AC | 2 ms
6,816 KB |
testcase_05 | AC | 2 ms
6,816 KB |
testcase_06 | AC | 2 ms
6,820 KB |
testcase_07 | AC | 2 ms
6,816 KB |
testcase_08 | AC | 2 ms
6,820 KB |
testcase_09 | AC | 2 ms
6,816 KB |
testcase_10 | AC | 2 ms
6,824 KB |
testcase_11 | AC | 2 ms
6,820 KB |
testcase_12 | AC | 2 ms
6,816 KB |
testcase_13 | AC | 14 ms
6,816 KB |
testcase_14 | AC | 49 ms
6,816 KB |
testcase_15 | AC | 51 ms
6,820 KB |
testcase_16 | AC | 74 ms
6,816 KB |
testcase_17 | AC | 137 ms
6,816 KB |
testcase_18 | AC | 136 ms
6,816 KB |
testcase_19 | AC | 137 ms
6,820 KB |
testcase_20 | AC | 125 ms
6,816 KB |
ソースコード
#line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/template/procon.hpp" #ifndef DEBUG // 提出時にassertはオフ #ifndef NDEBUG #define NDEBUG #endif // 定数倍高速化 #pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #endif #include <bits/stdc++.h> using namespace std; using ll = long long; using i64 = long long; using u64 = unsigned long long; #define ALL(x) (x).begin(), (x).end() template <class T> using vec = vector<T>; template <class T, class S> inline bool chmax(T &a, const S &b) { return (a < b ? a = b, 1 : 0); } template <class T, class S> inline bool chmin(T &a, const S &b) { return (a > b ? a = b, 1 : 0); } template <class T> constexpr T INF = 1'000'000'000; template <> constexpr int INF<int> = 1'000'000'000; template <> constexpr ll INF<ll> = ll(INF<int>) * INF<int> * 2; #line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/modint_dynamic.hpp" #line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/innermath_modint.hpp" #line 4 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/innermath_modint.hpp" namespace innermath_modint{ using ll = long long; using ull = unsigned long long; // xのmodを[0, mod)で返す constexpr ll safe_mod(ll x, ll mod) { x %= mod; if (x < 0) x += mod; return x; } constexpr ll pow_mod_constexpr(ll x, ll n, ll mod) { if (mod == 1) return 0; ll ret = 1; ll beki = safe_mod(x, mod); while (n) { // LSBから順に見る if (n & 1) { ret = (ret * beki) % mod; } beki = (beki * beki) % mod; n >>= 1; } return ret; } // int型(2^32以下)の高速な素数判定 constexpr bool is_prime_constexpr(int n) { if (n <= 1) return false; if (n == 2 || n == 7 || n == 61) return true; if (n % 2 == 0) return false; // ミラーラビン判定 int型ならa={2,7,61}で十分 constexpr ll bases[] = {2, 7, 61}; // n-1 = 2^r * d ll d = n - 1; while (d % 2 == 0) d >>= 1; // 素数modは1の平方根として非自明な解を持たない // つまり非自明な解がある→合成数 for (ll a : bases) { ll t = d; ll y = pow_mod_constexpr(a, t, n); // yが1またはn-1になれば抜ける while (t != n - 1 && y != 1 && y != n - 1) { y = (y * y) % n; t <<= 1; } // 1の平方根として1と-1以外の解(非自明な解)が存在 if (y != n - 1 && t % 2 == 0) { return false; } } return true; } // 拡張ユークリッドの互除法 g = gcd(a,b)と、ax = g (mod b)なる0 <= x < // b/gのペアを返す constexpr std::pair<ll, ll> inv_gcd(ll a, ll b) { a = safe_mod(a, b); // aがbの倍数 if (a == 0) return {b, 0}; // 以下 0 <= a < b // [1] s - m0 * a = 0 (mod b) // [2] t - m1 * a = 0 (mod b) // [3] s * |m1| + t * |m0| <= b ll s = b, t = a; ll m0 = 0, m1 = 1; while (t) { // s → s mod t // m0 → m0 - m1 * (s / t) ll u = s / t; s -= t * u; m0 -= m1 * u; { ll tmp = t; t = s; s = tmp; } { ll tmp = m1; m1 = m0; m0 = tmp; } } // s = gcd(a, b) // 終了の直前のステップにおいて // [1] k * s - m0 * a = 0 (mod b) // [2] s - m1 * a = 0 (mod b) // [3] (k * s) * |m1| + s * |m0| <= b // |m0| < b / s if (m0 < 0) m0 += b / s; return {s, m0}; } } #line 5 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/modint_dynamic.hpp" struct modint_dynamic { using ll = long long; private: ll value; static ll &getMod_inner() { static ll mod = 0; return mod; } public: modint_dynamic() noexcept : value(0) {}; modint_dynamic(ll x) noexcept : value(x % get_mod()) { if(value < 0) value += get_mod(); } // xがMODを超えないことが保障されている場合に定数倍高速化のために使用 static modint_dynamic raw(int x) noexcept { modint_dynamic v; assert(0 <= x && x < get_mod()); v.value = x; return v; } // コンストラクタの前にset_modを呼ぼう! static void set_mod(int mod) noexcept { assert(1 <= mod); getMod_inner() = mod; } static int get_mod() noexcept { return (int)(getMod_inner()); } ll val() const noexcept { return value; } modint_dynamic operator-() const noexcept { return modint_dynamic(-value); } modint_dynamic& operator++() noexcept { ++value; if(value == get_mod()) value = 0; return *this; } modint_dynamic& operator--() noexcept { if(value == 0) value = get_mod(); --value; return *this; } modint_dynamic operator++(int) noexcept { modint_dynamic cpy(*this); ++(*this); return cpy; } modint_dynamic operator--(int) noexcept { modint_dynamic cpy(*this); --(*this); return cpy; } modint_dynamic& operator+=(const modint_dynamic &rhs) noexcept { value += rhs.value; if(value >= get_mod()) value -= get_mod(); return *this; } modint_dynamic& operator-=(const modint_dynamic &rhs) noexcept { value += (get_mod() - rhs.value); if(value >= get_mod()) value -= get_mod(); return *this; } modint_dynamic& operator*=(const modint_dynamic &rhs) noexcept { value = (value * rhs.value) % get_mod(); return *this; } modint_dynamic operator+(const modint_dynamic &rhs) const noexcept { modint_dynamic cpy(*this); return cpy += rhs; } modint_dynamic operator-(const modint_dynamic &rhs) const noexcept { modint_dynamic cpy(*this); return cpy -= rhs; } modint_dynamic operator*(const modint_dynamic &rhs) const noexcept { modint_dynamic cpy(*this); return cpy *= rhs; } modint_dynamic pow(ll beki) { modint_dynamic curbekimod(*this); modint_dynamic ret(1); while(beki > 0) { if(beki & 1) ret *= curbekimod; curbekimod *= curbekimod; beki >>= 1; } return ret; } // valueの逆元を求める modint_dynamic inv() const noexcept { // 拡張ユークリッドの互除法 auto [gcd_value_mod, inv_value] = innermath_modint::inv_gcd(value, get_mod()); assert(gcd_value_mod == 1); return modint_dynamic(inv_value); } modint_dynamic& operator/=(const modint_dynamic &rhs) noexcept { return (*this) *= rhs.inv(); } modint_dynamic operator/(const modint_dynamic &rhs) const noexcept { modint_dynamic cpy(*this); return cpy /= rhs; } }; #line 3 "main.cpp" int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); ll N, M, B; cin >> N >> M >> B; modint_dynamic::set_mod(B); using mint = modint_dynamic; vec<ll> A(N); for(ll &a : A) cin >> a; // dpで求める // dp[i] = Aの部分列[0, i]における答 mint dp = 1; for(int i = 0; i < N; i++) { dp *= (mint(M).pow(A[i]) + 1); } cout << dp.val() << "\n"; }