提出 #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();
}
}
提出情報
提出日時
2025-03-23 22:41:01+0900
問題
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
結果
セット名
テストケース
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