QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#875650#9539. Disrupting Communicationswarner1129#WA 86ms3712kbC++205.0kb2025-01-30 00:27:272025-01-30 00:27:36

Judging History

This is the latest submission verdict.

  • [2025-01-30 00:27:36]
  • Judged
  • Verdict: WA
  • Time: 86ms
  • Memory: 3712kb
  • [2025-01-30 00:27:27]
  • Submitted

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;
}

详细

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'