提出 #64142162


ソースコード 拡げる

#ifdef LOCAL
    #include <bits/include_all.h>
#else
    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
#endif

#pragma GCC target ("avx2")
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")

#define f first
#define s second
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) ((int) (x).size())
#define pb push_back
#define mp make_pair
#define int long long

using namespace std;
using namespace __gnu_pbds;

template <typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> inline bool umin(T &a, const T &b) { if(a > b) { a = b; return 1; } return 0; }
template <typename T> inline bool umax(T &a, const T &b) { if(a < b) { a = b; return 1; } return 0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const ll mod = 998244353;
const ll base = 1e6 + 9;
const ll inf = 1e18;
const int MAX = 2e5 + 42;
const int LG = 20;

random_device rd;
mt19937 gen(rd());
uniform_int_distribution<ll> dis(1, inf);

constexpr int calculate_phi(int n) {
    if(n == 998244353 || n == 1000000007) return n - 1;
    int ans = n;
    for(int i = 2; i * i <= n; i++) {
        if(n % i == 0) {
            ans /= i; ans *= i - 1; while(n % i == 0) n /= i;
        }
    }
    if(n > 1) ans /= n, ans *= n - 1;
    return ans;
}

constexpr int phi_minus_one = calculate_phi(mod) - 1;

class Mint {
public:
    int x;

public:
    void norm() {
        x %= mod;
        if(x < 0) x += mod;
    }
    Mint(int a, bool small) {
        x = a;
        if(x >= mod) x -= mod;
        if(x < 0) x += mod;
    }
    Mint() { x = 0; }
    Mint(long long a) {
        if(a >= mod || a <= -mod) a %= mod;
        x = a;
        if(x < 0) x += mod;
    }
    Mint(const Mint &b) { x = b.x; }
    friend ostream &operator <<(ostream &out, const Mint &a) { out << a.x; return out; }
    friend istream &operator >>(istream &in, Mint &a) { in >> a.x; return in; }
    Mint operator +(const Mint &b) const & {
        return Mint(x + b.x, 1);
    }
    Mint operator +(int a) const & {
        return Mint(x + a, 1);
    }
    Mint operator -(const Mint &b) const & {
        return Mint(x - b.x, 1);
    }
    Mint operator -(int a) const & {
        return Mint(x - a, 1);
    }
    friend Mint operator -(const Mint &a) {
        return Mint(mod - a);
    }
    Mint operator *(const Mint &b) const & {
         return Mint(1LL * x * b.x);
    }
    Mint operator *(int a) const & {
        return Mint(1LL * x * a);
    }
    Mint &operator +=(const Mint &b) {
        x += b.x;
        if(x >= mod) x -= mod;
        return *this;
    }
    Mint &operator +=(int a) {
        x += a;
        if(x >= mod) x -= mod;
        return *this;
    }
    Mint &operator -=(const Mint &b) {
        x += mod - b.x;
        if(x >= mod) x -= mod;
        return *this;
    }
    Mint &operator -=(int a) {
        x += mod - a;
        if(x >= mod) x -= mod;
        return *this;
    }
    Mint &operator *=(const Mint &b) {
        x = (long long) x * b.x % mod;
        return *this;
    }
    Mint &operator *=(int a) {
        x = (long long) x * a % mod;
        return *this;
    }
    Mint &operator /=(const Mint &b) {
        x = (long long) x * b.inv().x % mod;
        return *this;
    }
    Mint &operator /=(int a) {
        x = (long long) x * Mint(a, 1).inv().x % mod;
        return *this;
    }
    Mint &operator ++() {
        if(++x == mod) x = 0;
        return *this;
    }
    Mint operator ++(int32_t) {
        Mint ans(*this);
        if(++x == mod) x = 0;
        return ans;
    }
    Mint &operator --() {
        if(--x == -1) x = mod - 1;
        return *this;
    }
    Mint operator --(int32_t) {
        Mint ans(*this);
        if(--x == -1) x = mod - 1;
        return ans;
    }
    Mint bpow(long long n) const & {
        Mint a(x);
        Mint ans(1);
        while(n) {
            if(n & 1) ans *= a;
            n >>= 1;
            a *= a;
        }
        return ans;
    }
    Mint inv() const & {
        return bpow(phi_minus_one);
    }
    Mint operator /(const Mint &b) const & {
        return b.inv() * x;
    }
    Mint operator /(int a) const & {
        return Mint(a, 1).inv() * x;
    }
    friend Mint operator -(int a, const Mint &b) {
        Mint res(b - a);
        res.x = mod - res.x;
        if(res.x == mod) res.x = 0;
        return res;
    }
    friend Mint operator +(int a, const Mint &b) {
        return Mint(b + a);
    }
    friend Mint operator *(int a, const Mint &b) {
        return Mint(b * a);
    }
    friend Mint operator /(int a, const Mint &b) {
        return Mint(a, 1) * b.inv();
    }
    Mint &operator=(const Mint &b) {
        x = b.x;
        return *this;
    }
    bool operator==(int a) const & {
        return (x == a);
    }
    bool operator!=(int a) const & {
        return (x != a);
    }
    bool operator==(const Mint &b) const & {
        return (x == b.x);
    }
    bool operator!=(const Mint &b) const & {
        return (x != b.x);
    }
    friend bool operator==(int a, const Mint &b) {
        return (b.x == a);
    }
    friend bool operator!=(int a, const Mint &b) {
        return (b.x != a);
    }
};

Mint fact[MAX], inv[MAX];

Mint C(int n, int k) {
    if(n < k || k < 0) return 0;
    return fact[n] * inv[k] * inv[n - k];
}

void solve() {
    int n, q;
    cin >> n >> q;
    vector<int> a(n);
    for(int i = 1; i < n; i++) {
        cin >> a[i];
    }

    vector<Mint> pref(n);
    pref[0] = 1;
    for(int i = 1; i < n; i++) pref[i] = 1 + Mint(i).inv();
    for(int i = 1; i < n; i++) pref[i] *= pref[i - 1];
    auto pref_inv = pref;
    for(auto &i : pref_inv) i = i.inv();
    vector<Mint> inv_val(n + 1);
    for(int i = 1; i <= n; i++) inv_val[i] = fact[i - 1] * inv[i];

    Mint sum = 0;
    vector<Mint> precalc(n);
    for(int v = 0; v < n;v++) {
        precalc[v] = sum * fact[n - 1] * pref[v - 1] * pref_inv[0] * inv_val[v] + a[v] * fact[n - 1] * pref[v - 1] * pref_inv[0] * inv_val[v];
        sum += a[v] * inv_val[v + 1];
    }

    auto p_precalc = precalc;
    for(int i = 1; i < n; i++) p_precalc[i] += p_precalc[i - 1];
    p_precalc.insert(p_precalc.begin(), 0);

    vector<Mint> dp(n);
    vector<Mint> pref_dp(n);
    for(int i = 1; i < n; i++) {
        dp[i] += pref_dp[i - 1] * 2 * inv_val[i];
        dp[i] += p_precalc[i] * 2 * inv_val[i];

        pref_dp[i] = pref_dp[i - 1] + dp[i];
    }

    auto calc = [&](int u, int v) -> Mint {
        Mint ans = (u? pref_dp[u - 1] : Mint(0)) * inv_val[u] * inv_val[v] * pref[v - 1] * pref_inv[u];
        ans += p_precalc[u] * inv_val[u] * inv_val[v] * pref[v - 1] * pref_inv[u];

        return ans;
    };

    auto get = [&](int u, int v) -> Mint {
        if(u == v) return 0;
        Mint ans = precalc[u] + precalc[v] - 2 * precalc[u] * pref[v - 1] * pref_inv[u] * inv_val[v];

        ans -= 2 * calc(u, v);

        return ans;
    };

    while(q--) {
        int u, v;
        cin >> u >> v; u--, v--;
        cout << get(u, v) << '\n';
    }
}

signed main() {
    fact[0] = 1; for(int i = 1; i < MAX; i++) fact[i] = fact[i - 1] * i;
    inv[MAX - 1] = 1 / fact[MAX - 1];
    for(int i = MAX - 1; i; i--) inv[i - 1] = inv[i] * i; assert(inv[0] == 1);
    ios_base::sync_with_stdio(0); cin.tie(0);
    int ttt = 1;
//    cin >> ttt;
    while(ttt--) {
        solve();
    }
}

提出情報

提出日時
問題 E - Random Tree Distance
ユーザ nife
言語 C++ 20 (gcc 12.2)
得点 900
コード長 7826 Byte
結果 AC
実行時間 121 ms
メモリ 18716 KiB

コンパイルエラー

Main.cpp: In constructor ‘Mint::Mint(long long int, bool)’:
Main.cpp:68:22: warning: unused parameter ‘small’ [-Wunused-parameter]
   68 |     Mint(int a, bool small) {
      |                 ~~~~~^~~~~
Main.cpp: In function ‘int main()’:
Main.cpp:285:5: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation]
  285 |     for(int i = MAX - 1; i; i--) inv[i - 1] = inv[i] * i; assert(inv[0] == 1);
      |     ^~~
In file included from /usr/include/c++/12/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp:45,
                 from /usr/include/c++/12/ext/pb_ds/detail/container_base_dispatch.hpp:90,
                 from /usr/include/c++/12/ext/pb_ds/assoc_container.hpp:48,
                 from Main.cpp:5:
Main.cpp:285:59: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘for’
  285 |     for(int i = MAX - 1; i; i--) inv[i - 1] = inv[i] * i; assert(inv[0] == 1);
      |                                                           ^~~~~~

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 900 / 900
結果
AC × 3
AC × 40
セット名 テストケース
Sample 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt
All 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt, 01_handmade_01.txt, 01_handmade_02.txt, 01_handmade_03.txt, 02_small_01.txt, 02_small_02.txt, 02_small_03.txt, 02_small_04.txt, 02_small_05.txt, 03_medium_01.txt, 03_medium_02.txt, 03_medium_03.txt, 03_medium_04.txt, 03_medium_05.txt, 04_large_01.txt, 04_large_02.txt, 04_large_03.txt, 04_large_04.txt, 04_large_05.txt, 05_max_01.txt, 05_max_02.txt, 05_max_03.txt, 05_max_04.txt, 05_max_05.txt, 05_max_06.txt, 05_max_07.txt, 05_max_08.txt, 05_max_09.txt, 05_max_10.txt, 06_distinct_u_02.txt, 06_distinct_u_03.txt, 06_distinct_u_04.txt, 06_distinct_u_05.txt, 06_distinct_u_06.txt, 06_distinct_u_07.txt, 06_distinct_u_08.txt, 06_distinct_u_09.txt, 06_distinct_u_10.txt
ケース名 結果 実行時間 メモリ
00_sample_01.txt AC 4 ms 6612 KiB
00_sample_02.txt AC 4 ms 6572 KiB
00_sample_03.txt AC 4 ms 6744 KiB
01_handmade_01.txt AC 4 ms 6620 KiB
01_handmade_02.txt AC 103 ms 18476 KiB
01_handmade_03.txt AC 94 ms 18616 KiB
02_small_01.txt AC 4 ms 6460 KiB
02_small_02.txt AC 4 ms 6744 KiB
02_small_03.txt AC 4 ms 6616 KiB
02_small_04.txt AC 4 ms 6524 KiB
02_small_05.txt AC 4 ms 6572 KiB
03_medium_01.txt AC 7 ms 6692 KiB
03_medium_02.txt AC 35 ms 6656 KiB
03_medium_03.txt AC 26 ms 6644 KiB
03_medium_04.txt AC 13 ms 6604 KiB
03_medium_05.txt AC 11 ms 6636 KiB
04_large_01.txt AC 75 ms 12964 KiB
04_large_02.txt AC 57 ms 11656 KiB
04_large_03.txt AC 78 ms 14788 KiB
04_large_04.txt AC 52 ms 14836 KiB
04_large_05.txt AC 60 ms 9236 KiB
05_max_01.txt AC 120 ms 18644 KiB
05_max_02.txt AC 118 ms 18652 KiB
05_max_03.txt AC 118 ms 18612 KiB
05_max_04.txt AC 118 ms 18652 KiB
05_max_05.txt AC 119 ms 18664 KiB
05_max_06.txt AC 118 ms 18484 KiB
05_max_07.txt AC 119 ms 18560 KiB
05_max_08.txt AC 118 ms 18636 KiB
05_max_09.txt AC 118 ms 18660 KiB
05_max_10.txt AC 120 ms 18716 KiB
06_distinct_u_02.txt AC 118 ms 18644 KiB
06_distinct_u_03.txt AC 118 ms 18652 KiB
06_distinct_u_04.txt AC 118 ms 18600 KiB
06_distinct_u_05.txt AC 119 ms 18576 KiB
06_distinct_u_06.txt AC 119 ms 18652 KiB
06_distinct_u_07.txt AC 119 ms 18560 KiB
06_distinct_u_08.txt AC 119 ms 18568 KiB
06_distinct_u_09.txt AC 121 ms 18480 KiB
06_distinct_u_10.txt AC 119 ms 18572 KiB