QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#875650 | #9539. Disrupting Communications | warner1129# | WA | 86ms | 3712kb | C++20 | 5.0kb | 2025-01-30 00:27:27 | 2025-01-30 00:27:36 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
template<class F, class S>
ostream &operator<<(ostream &s, const pair<F, S> &v) {
s << "(" << v.first << ", " << v.second << ")";
return s;
}
template<ranges::range T> requires (!is_convertible_v<T, string_view>)
istream &operator>>(istream &s, T &&v) {
for (auto &&x : v) s >> x;
return s;
}
template<ranges::range T> requires (!is_convertible_v<T, string_view>)
ostream &operator<<(ostream &s, T &&v) {
for (auto &&x : v) s << x << ' ';
return s;
}
#ifdef LOCAL
template<class... T> void dbg(T... x) {
char e{};
((cerr << e << x, e = ' '), ...);
}
#define debug(x...) dbg(#x, '=', x, '\n')
#else
#define debug(...) ((void)0)
#endif
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define ff first
#define ss second
template<class T> inline constexpr T inf = numeric_limits<T>::max() / 2;
bool chmin(auto &a, auto b) { return (b < a and (a = b, true)); }
bool chmax(auto &a, auto b) { return (a < b and (a = b, true)); }
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
constexpr i64 mod = 998244353;
struct Tree {
int n, lgN;
vector<vector<int>> G;
vector<vector<int>> st;
vector<int> in, out, dep, pa, seq;
Tree(int n) : n(n), G(n), in(n), out(n), dep(n), pa(n, -1) {}
int cmp(int a, int b) {
return dep[a] < dep[b] ? a : b;
}
void dfs(int u) {
erase(G[u], pa[u]);
in[u] = seq.size();
seq.push_back(u);
for (int v : G[u]) {
dep[v] = dep[u] + 1;
pa[v] = u;
dfs(v);
}
out[u] = seq.size();
}
void build() {
seq.reserve(n);
dfs(0);
lgN = __lg(n);
st.assign(lgN + 1, vector<int>(n));
st[0] = seq;
for (int i = 0; i < lgN; i++)
for (int j = 0; j + (2 << i) <= n; j++)
st[i + 1][j] = cmp(st[i][j], st[i][j + (1 << i)]);
}
int inside(int x, int y) {
return in[x] <= in[y] and in[y] < out[x];
}
int lca(int x, int y) {
if (x == y) return x;
if ((x = in[x] + 1) > (y = in[y] + 1))
swap(x, y);
int h = __lg(y - x);
return pa[cmp(st[h][x], st[h][y - (1 << h)])];
}
int dist(int x, int y) {
return dep[x] + dep[y] - 2 * dep[lca(x, y)];
}
int rootPar(int r, int x) {
if (r == x) return -1;
if (!inside(x, r)) return pa[x];
return *--upper_bound(all(G[x]), r,
[&](int a, int b) -> bool {
return in[a] < in[b];
});
}
int size(int x) { return out[x] - in[x]; }
int rootSiz(int r, int x) {
if (r == x) return n;
if (!inside(x, r)) return size(x);
return n - size(rootPar(r, x));
}
int rootLca(int a, int b, int c) {
return lca(a, b) ^ lca(b, c) ^ lca(c, a);
}
};
void solve() {
int n, q;
cin >> n >> q;
vector G(n, vector<int>{});
for (int i = 1; i < n; i++) {
int p;
cin >> p;
p--;
G[p].push_back(i);
}
Tree tree(n);
tree.G = G;
tree.build();
vector dp(n, array<i64, 2>{});
auto dfs = [&](auto &&self, int u) -> void {
dp[u][1] = 1;
for (int v : G[u]) {
self(self, v);
(dp[u][0] += dp[v][0] + dp[v][1]) %= mod;
(dp[u][1] *= (1 + dp[v][1])) %= mod;
}
};
dfs(dfs, 0);
vector<i64> up(n);
auto dfs2 = [&](auto &&self, int u) -> void {
const int siz = G[u].size();
vector<i64> pre(siz), suf(siz);
for (int i = 0; i < siz; i++) {
int v = G[u][i];
pre[i] = (dp[v][1] + 1);
if (i) {
(pre[i] *= pre[i - 1]) %= mod;
}
}
for (int i = siz - 1; i >= 0; i--) {
int v = G[u][i];
suf[i] = (dp[v][1] + 1);
if (i + 1 < siz) {
(suf[i] *= suf[i + 1]) %= mod;
}
}
for (int i = 0; i < siz; i++) {
int v = G[u][i];
up[v] = up[u] * (i == 0 ? 1 : pre[i - 1]) % mod * (i == siz - 1 ? 1 : suf[i + 1]) % mod;
(up[v] += 1) %= mod;
}
};
up[0] = 1;
dfs2(dfs2, 0);
vector<i64> val(n), sum(n);
auto dfs3 = [&](auto &&self, int u) -> void {
val[u] = (mod * 2 - dp[u][0] - dp[u][1]) % mod;
for (int v : G[u]) {
(val[u] += dp[v][0] + dp[v][1]) %= mod;
}
(sum[u] += val[u]) %= mod;
for (int v : G[u]) {
sum[v] = sum[u];
self(self, v);
}
};
dfs3(dfs3, 0);
while (q--) {
int x, y;
cin >> x >> y;
x--, y--;
int l = tree.lca(x, y);
i64 ans = 0;
ans = sum[x] + sum[y] - 2 * sum[l] + val[l];
((ans %= mod) += mod) %= mod;
(ans += dp[0][0] + dp[0][1]) %= mod;
ans -= (up[l] - 1) * dp[l][1] % mod;
((ans %= mod) += mod) %= mod;
ans = dp[0][0] + dp[0][1] - ans;
((ans %= mod) += mod) %= mod;
cout << ans << '\n';
}
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
cin.exceptions(cin.failbit);
int t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3712kb
input:
2 3 2 1 1 2 3 1 2 5 3 1 1 2 2 4 5 2 4 2 3
output:
6 5 14 13 15
result:
ok 5 lines
Test #2:
score: -100
Wrong Answer
time: 86ms
memory: 3712kb
input:
3000 98 100 1 2 1 3 5 3 2 5 5 4 3 7 12 10 12 8 10 4 4 3 10 14 11 11 22 23 14 20 29 1 18 7 12 29 20 29 12 21 6 20 3 25 7 21 16 44 38 44 7 11 5 24 34 24 41 48 56 58 56 3 26 55 62 33 9 38 63 39 3 67 14 24 60 35 1 22 74 36 57 61 55 46 44 12 16 60 44 50 22 58 78 15 57 57 75 88 15 43 28 67 66 3 39 6 19 84...
output:
964062690 21569 8 964050185 27 17418 21812 964064991 15 964045750 964065023 959849545 536098301 964045791 964064966 964046253 964052677 4874 964050627 17393 188617843 964065041 104 4875 964046253 536098346 480 964052584 484 964046254 16945 56 21839 536098098 271 5330 17426 21538 964052955 21858 9640...
result:
wrong answer 2nd lines differ - expected: '949799024', found: '21569'