結果
問題 | No.2305 [Cherry 5th Tune N] Until That Day... |
ユーザー |
👑 ![]() |
提出日時 | 2023-05-20 00:00:02 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 18,692 bytes |
コンパイル時間 | 5,648 ms |
コンパイル使用メモリ | 319,440 KB |
実行使用メモリ | 6,824 KB |
最終ジャッジ日時 | 2024-12-20 03:09:09 |
合計ジャッジ時間 | 14,320 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 1 WA * 20 |
ソースコード
#include <bits/stdc++.h>using namespace std;#define FOR(i,m,n) for(int i=(m);i<(n);++i)#define REP(i,n) FOR(i,0,n)#define ALL(v) (v).begin(),(v).end()using ll = long long;constexpr int INF = 0x3f3f3f3f;constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;constexpr double EPS = 1e-8;constexpr int MOD = 998244353;// constexpr int MOD = 1000000007;constexpr int DY4[]{1, 0, -1, 0}, DX4[]{0, -1, 0, 1};constexpr int DY8[]{1, 1, 0, -1, -1, -1, 0, 1};constexpr int DX8[]{0, -1, -1, -1, 0, 1, 1, 1};template <typename T, typename U>inline bool chmax(T& a, U b) { return a < b ? (a = b, true) : false; }template <typename T, typename U>inline bool chmin(T& a, U b) { return a > b ? (a = b, true) : false; }struct IOSetup {IOSetup() {std::cin.tie(nullptr);std::ios_base::sync_with_stdio(false);std::cout << fixed << setprecision(20);}} iosetup;template <unsigned int M>struct MInt {unsigned int v;constexpr MInt() : v(0) {}constexpr MInt(const long long x) : v(x >= 0 ? x % M : x % M + M) {}static constexpr MInt raw(const int x) {MInt x_;x_.v = x;return x_;}static constexpr int get_mod() { return M; }static constexpr void set_mod(const int divisor) {assert(std::cmp_equal(divisor, M));}static void init(const int x) {inv<true>(x);fact(x);fact_inv(x);}template <bool MEMOIZES = false>static MInt inv(const int n) {// assert(0 <= n && n < M && std::gcd(n, M) == 1);static std::vector<MInt> inverse{0, 1};const int prev = inverse.size();if (n < prev) return inverse[n];if constexpr (MEMOIZES) {// "n!" and "M" must be disjoint.inverse.resize(n + 1);for (int i = prev; i <= n; ++i) {inverse[i] = -inverse[M % i] * raw(M / i);}return inverse[n];}int u = 1, v = 0;for (unsigned int a = n, b = M; b;) {const unsigned int q = a / b;std::swap(a -= q * b, b);std::swap(u -= q * v, v);}return u;}static MInt fact(const int n) {static std::vector<MInt> factorial{1};if (const int prev = factorial.size(); n >= prev) {factorial.resize(n + 1);for (int i = prev; i <= n; ++i) {factorial[i] = factorial[i - 1] * i;}}return factorial[n];}static MInt fact_inv(const int n) {static std::vector<MInt> f_inv{1};if (const int prev = f_inv.size(); n >= prev) {f_inv.resize(n + 1);f_inv[n] = inv(fact(n).v);for (int i = n; i > prev; --i) {f_inv[i - 1] = f_inv[i] * i;}}return f_inv[n];}static MInt nCk(const int n, const int k) {if (n < 0 || n < k || k < 0) [[unlikely]] return MInt();return fact(n) * (n - k < k ? fact_inv(k) * fact_inv(n - k) :fact_inv(n - k) * fact_inv(k));}static MInt nPk(const int n, const int k) {return n < 0 || n < k || k < 0 ? MInt() : fact(n) * fact_inv(n - k);}static MInt nHk(const int n, const int k) {return n < 0 || k < 0 ? MInt() : (k == 0 ? 1 : nCk(n + k - 1, k));}static MInt large_nCk(long long n, const int k) {if (n < 0 || n < k || k < 0) [[unlikely]] return MInt();inv<true>(k);MInt res = 1;for (int i = 1; i <= k; ++i) {res *= inv(i) * n--;}return res;}constexpr MInt pow(long long exponent) const {MInt res = 1, tmp = *this;for (; exponent > 0; exponent >>= 1) {if (exponent & 1) res *= tmp;tmp *= tmp;}return res;}constexpr MInt& operator+=(const MInt& x) {if ((v += x.v) >= M) v -= M;return *this;}constexpr MInt& operator-=(const MInt& x) {if ((v += M - x.v) >= M) v -= M;return *this;}constexpr MInt& operator*=(const MInt& x) {v = (unsigned long long){v} * x.v % M;return *this;}MInt& operator/=(const MInt& x) { return *this *= inv(x.v); }constexpr auto operator<=>(const MInt& x) const = default;constexpr MInt& operator++() {if (++v == M) [[unlikely]] v = 0;return *this;}constexpr MInt operator++(int) {const MInt res = *this;++*this;return res;}constexpr MInt& operator--() {v = (v == 0 ? M - 1 : v - 1);return *this;}constexpr MInt operator--(int) {const MInt res = *this;--*this;return res;}constexpr MInt operator+() const { return *this; }constexpr MInt operator-() const { return raw(v ? M - v : 0); }constexpr MInt operator+(const MInt& x) const { return MInt(*this) += x; }constexpr MInt operator-(const MInt& x) const { return MInt(*this) -= x; }constexpr MInt operator*(const MInt& x) const { return MInt(*this) *= x; }MInt operator/(const MInt& x) const { return MInt(*this) /= x; }friend std::ostream& operator<<(std::ostream& os, const MInt& x) {return os << x.v;}friend std::istream& operator>>(std::istream& is, MInt& x) {long long v;is >> v;x = MInt(v);return is;}};using ModInt = MInt<MOD>;#include <atcoder/convolution>template <unsigned int T>struct NumberTheoreticTransform {using ModInt = MInt<T>;NumberTheoreticTransform() = default;template <typename U>std::vector<ModInt> dft(const std::vector<U>& a);void idft(std::vector<ModInt>* a);template <typename U>std::vector<ModInt> convolution(const std::vector<U>& a,const std::vector<U>& b) {const int a_size = a.size(), b_size = b.size();std::vector<atcoder::static_modint<T>> c(a_size), d(b_size);for (int i = 0; i < a_size; ++i) {c[i] = atcoder::static_modint<T>::raw(ModInt(a[i]).v);}for (int i = 0; i < b_size; ++i) {d[i] = atcoder::static_modint<T>::raw(ModInt(b[i]).v);}c = atcoder::convolution(c, d);const int c_size = c.size();std::vector<ModInt> res(c_size);for (int i = 0; i < c_size; ++i) {res[i] = ModInt::raw(c[i].val());}return res;}};template <typename T>struct FormalPowerSeries {std::vector<T> coef;explicit FormalPowerSeries(const int deg = 0) : coef(deg + 1, 0) {}explicit FormalPowerSeries(const std::vector<T>& coef) : coef(coef) {}FormalPowerSeries(const std::initializer_list<T> init): coef(init.begin(), init.end()) {}template <typename InputIter>explicit FormalPowerSeries(const InputIter first, const InputIter last): coef(first, last) {}inline const T& operator[](const int term) const { return coef[term]; }inline T& operator[](const int term) { return coef[term]; }using Mult = std::function<std::vector<T>(const std::vector<T>&,const std::vector<T>&)>;using Sqrt = std::function<bool(const T&, T*)>;static void set_mult(const Mult mult) { get_mult() = mult; }static void set_sqrt(const Sqrt sqrt) { get_sqrt() = sqrt; }void resize(const int deg) { coef.resize(deg + 1, 0); }void shrink() {while (coef.size() > 1 && coef.back() == 0) coef.pop_back();}int degree() const { return std::ssize(coef) - 1; }FormalPowerSeries& operator=(const std::vector<T>& coef_) {coef = coef_;return *this;}FormalPowerSeries& operator=(const FormalPowerSeries& x) = default;FormalPowerSeries& operator+=(const FormalPowerSeries& x) {const int deg_x = x.degree();if (deg_x > degree()) resize(deg_x);for (int i = 0; i <= deg_x; ++i) {coef[i] += x[i];}return *this;}FormalPowerSeries& operator-=(const FormalPowerSeries& x) {const int deg_x = x.degree();if (deg_x > degree()) resize(deg_x);for (int i = 0; i <= deg_x; ++i) {coef[i] -= x[i];}return *this;}FormalPowerSeries& operator*=(const T x) {for (T& e : coef) e *= x;return *this;}FormalPowerSeries& operator*=(const FormalPowerSeries& x) {return *this = get_mult()(coef, x.coef);}FormalPowerSeries& operator/=(const T x) {assert(x != 0);return *this *= static_cast<T>(1) / x;}FormalPowerSeries& operator/=(const FormalPowerSeries& x) {const int n = degree() - x.degree() + 1;if (n <= 0) return *this = FormalPowerSeries();const std::vector<T> tmp = get_mult()(std::vector<T>(coef.rbegin(), std::next(coef.rbegin(), n)),FormalPowerSeries(x.coef.rbegin(),std::next(x.coef.rbegin(), std::min(x.degree() + 1, n))).inv(n - 1).coef);return *this = FormalPowerSeries(std::prev(tmp.rend(), n), tmp.rend());}FormalPowerSeries& operator%=(const FormalPowerSeries& x) {if (x.degree() == 0) return *this = FormalPowerSeries{0};*this -= *this / x * x;resize(x.degree() - 1);return *this;}FormalPowerSeries& operator<<=(const int n) {coef.insert(coef.begin(), n, 0);return *this;}FormalPowerSeries& operator>>=(const int n) {if (degree() < n) return *this = FormalPowerSeries();coef.erase(coef.begin(), coef.begin() + n);return *this;}bool operator==(FormalPowerSeries x) const {x.shrink();FormalPowerSeries y = *this;y.shrink();return x.coef == y.coef;}FormalPowerSeries operator+() const { return *this; }FormalPowerSeries operator-() const {FormalPowerSeries res = *this;for (T& e : res.coef) e = -e;return res;}FormalPowerSeries operator+(const FormalPowerSeries& x) const {return FormalPowerSeries(*this) += x;}FormalPowerSeries operator-(const FormalPowerSeries& x) const {return FormalPowerSeries(*this) -= x;}FormalPowerSeries operator*(const T x) const {return FormalPowerSeries(*this) *= x;}FormalPowerSeries operator*(const FormalPowerSeries& x) const {return FormalPowerSeries(*this) *= x;}FormalPowerSeries operator/(const T x) const {return FormalPowerSeries(*this) /= x;}FormalPowerSeries operator/(const FormalPowerSeries& x) const {return FormalPowerSeries(*this) /= x;}FormalPowerSeries operator%(const FormalPowerSeries& x) const {return FormalPowerSeries(*this) %= x;}FormalPowerSeries operator<<(const int n) const {return FormalPowerSeries(*this) <<= n;}FormalPowerSeries operator>>(const int n) const {return FormalPowerSeries(*this) >>= n;}T horner(const T x) const {return std::accumulate(coef.rbegin(), coef.rend(), static_cast<T>(0),[x](const T l, const T r) -> T { return l * x + r; });}FormalPowerSeries differential() const {const int deg = degree();assert(deg >= 0);FormalPowerSeries res(std::max(deg - 1, 0));for (int i = 1; i <= deg; ++i) {res[i - 1] = coef[i] * i;}return res;}FormalPowerSeries exp(const int deg) const {assert(coef[0] == 0);const int n = coef.size();const FormalPowerSeries one{1};FormalPowerSeries res = one;for (int i = 1; i <= deg; i <<= 1) {res *= FormalPowerSeries(coef.begin(),std::next(coef.begin(), std::min(n, i << 1)))- res.log((i << 1) - 1) + one;res.coef.resize(i << 1);}res.resize(deg);return res;}FormalPowerSeries exp() const { return exp(degree()); }FormalPowerSeries inv(const int deg) const {assert(coef[0] != 0);const int n = coef.size();FormalPowerSeries res{static_cast<T>(1) / coef[0]};for (int i = 1; i <= deg; i <<= 1) {res = res + res - res * res * FormalPowerSeries(coef.begin(), std::next(coef.begin(), std::min(n, i << 1)));res.coef.resize(i << 1);}res.resize(deg);return res;}FormalPowerSeries inv() const { return inv(degree()); }FormalPowerSeries log(const int deg) const {assert(coef[0] == 1);FormalPowerSeries integrand = differential() * inv(deg - 1);integrand.resize(deg);for (int i = deg; i > 0; --i) {integrand[i] = integrand[i - 1] / i;}integrand[0] = 0;return integrand;}FormalPowerSeries log() const { return log(degree()); }FormalPowerSeries pow(long long exponent, const int deg) const {const int n = coef.size();if (exponent == 0) {FormalPowerSeries res(deg);if (deg != -1) [[unlikely]] res[0] = 1;return res;}assert(deg >= 0);for (int i = 0; i < n; ++i) {if (coef[i] == 0) continue;if (i > deg / exponent) break;const long long shift = exponent * i;T tmp = 1, base = coef[i];for (long long e = exponent; e > 0; e >>= 1) {if (e & 1) tmp *= base;base *= base;}const FormalPowerSeries res = ((*this >> i) / coef[i]).log(deg - shift);return ((res * exponent).exp(deg - shift) * tmp) << shift;}return FormalPowerSeries(deg);}FormalPowerSeries pow(const long long exponent) const {return pow(exponent, degree());}FormalPowerSeries mod_pow(long long exponent,const FormalPowerSeries& md) const {const int deg = md.degree() - 1;if (deg < 0) [[unlikely]] return FormalPowerSeries(-1);const FormalPowerSeries inv_rev_md =FormalPowerSeries(md.coef.rbegin(), md.coef.rend()).inv();const auto mod_mult = [&md, &inv_rev_md, deg](FormalPowerSeries* multiplicand, const FormalPowerSeries& multiplier)-> void {*multiplicand *= multiplier;if (deg < multiplicand->degree()) {const int n = multiplicand->degree() - deg;const FormalPowerSeries quotient =FormalPowerSeries(multiplicand->coef.rbegin(),std::next(multiplicand->coef.rbegin(), n))* FormalPowerSeries(inv_rev_md.coef.begin(),std::next(inv_rev_md.coef.begin(), std::min(deg + 2, n)));*multiplicand -=FormalPowerSeries(std::prev(quotient.coef.rend(), n),quotient.coef.rend()) * md;multiplicand->resize(deg);}multiplicand->shrink();};FormalPowerSeries res{1}, base = *this;for (; exponent > 0; exponent >>= 1) {if (exponent & 1) mod_mult(&res, base);mod_mult(&base, base);}return res;}FormalPowerSeries sqrt(const int deg) const {const int n = coef.size();if (coef[0] == 0) {for (int i = 1; i < n; ++i) {if (coef[i] == 0) continue;if (i & 1) return FormalPowerSeries(-1);const int shift = i >> 1;if (deg < shift) break;FormalPowerSeries res = (*this >> i).sqrt(deg - shift);if (res.coef.empty()) return FormalPowerSeries(-1);res <<= shift;res.resize(deg);return res;}return FormalPowerSeries(deg);}T s;if (!get_sqrt()(coef.front(), &s)) return FormalPowerSeries(-1);FormalPowerSeries res{s};const T half = static_cast<T>(1) / 2;for (int i = 1; i <= deg; i <<= 1) {res = (FormalPowerSeries(coef.begin(),std::next(coef.begin(), std::min(n, i << 1)))* res.inv((i << 1) - 1) + res) * half;}res.resize(deg);return res;}FormalPowerSeries sqrt() const { return sqrt(degree()); }FormalPowerSeries translate(const T c) const {const int n = coef.size();std::vector<T> fact(n, 1), inv_fact(n, 1);for (int i = 1; i < n; ++i) {fact[i] = fact[i - 1] * i;}inv_fact[n - 1] = static_cast<T>(1) / fact[n - 1];for (int i = n - 1; i > 0; --i) {inv_fact[i - 1] = inv_fact[i] * i;}std::vector<T> g(n), ex(n);for (int i = 0; i < n; ++i) {g[i] = coef[i] * fact[i];}std::reverse(g.begin(), g.end());T pow_c = 1;for (int i = 0; i < n; ++i) {ex[i] = pow_c * inv_fact[i];pow_c *= c;}const std::vector<T> conv = get_mult()(g, ex);FormalPowerSeries res(n - 1);for (int i = 0; i < n; ++i) {res[i] = conv[n - 1 - i] * inv_fact[i];}return res;}private:static Mult& get_mult() {static Mult mult = [](const std::vector<T>& a, const std::vector<T>& b)-> std::vector<T> {const int n = a.size(), m = b.size();std::vector<T> res(n + m - 1, 0);for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {res[i + j] += a[i] * b[j];}}return res;};return mult;}static Sqrt& get_sqrt() {static Sqrt sqrt = [](const T&, T*) -> bool { return false; };return sqrt;}};template <typename T>T bostan_mori(FormalPowerSeries<T> p, FormalPowerSeries<T> q, long long n) {q.shrink();const int d = q.degree();assert(d >= 0 && q[0] != 0);T res = 0;p.shrink();if (p.degree() >= d) {const FormalPowerSeries<T> quotient = p / q;p -= quotient * q;p.shrink();if (n <= quotient.degree()) res += quotient[n];}if (d == 0 || (p.degree() == 0 && p[0] == 0)) return res;p.resize(d - 1);for (; n > 0; n >>= 1) {FormalPowerSeries<T> tmp = q;for (int i = 1; i <= d; i += 2) {tmp[i] = -tmp[i];}p *= tmp;if (n & 1) {for (int i = 0; i < d; ++i) {p[i] = p[(i << 1) + 1];}} else {for (int i = 1; i < d; ++i) {p[i] = p[i << 1];}}p.resize(d - 1);q *= tmp;for (int i = 1; i <= d; ++i) {q[i] = q[i << 1];}q.resize(d);}return res + p[0] / q[0];}int main() {FormalPowerSeries<ModInt>::set_mult([](const vector<ModInt>& a, const vector<ModInt>& b) -> vector<ModInt> {static NumberTheoreticTransform<MOD> ntt;return ntt.convolution(a, b);});const FormalPowerSeries<ModInt> one{1};int n; cin >> n;vector<vector<int>> graph(n + 1);FOR(i, 1, n + 1) {int p; cin >> p;graph[p].emplace_back(i);}vector<int> w(n + 1, 0); FOR(i, 1, n + 1) cin >> w[i];int q; cin >> q;while (q--) {int a, k; cin >> a >> k;FormalPowerSeries<ModInt> f(n + 1), fy(n + 1), h(n), hy(n);const auto dfs = [&](auto dfs, const int node, const ModInt& prob, const int depth, const bool is_passed) -> void {if (graph[node].empty()) {(is_passed ? fy : f)[depth + 1] += prob;return;}(is_passed ? hy : h)[depth] += prob;ll den = 0;for (const int e : graph[node]) den += w[e];for (const int e : graph[node]) {dfs(dfs, e, prob * w[e] / den, depth + 1, is_passed || (e == a));}};dfs(dfs, 0, 1, 0, a == 0);cout << bostan_mori((h + hy) * fy + (one - f - fy) * hy, (one - f - fy) * (one - f - fy), k) << '\n';}return 0;}