样例过了,但是全 WA。
不知道为什么。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define int long long
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
const int N = 1e5 + 10, mod = 998244353;
int h[N], e[N], ne[N], idx;
int fa[N], dep[N], sz[N], nw[N];
int son[N], top[N], id[N], cnt;
int s[N], ans[N], n, m, k;
struct Queries {
int x, y;
int id;
bool operator < (const Queries& tmp)const {
return x < tmp.x;
}
}q[N];
LL qpow(LL a, LL b, LL p) {
LL res = 1;
while (b) {
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
void add(int a, int b) {
e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
}
void dfs1(int u, int father, int depth) {
fa[u] = father, dep[u] = depth, sz[u] = 1;
for (int i = h[u]; i; i = ne[i]) {
int j = e[i];
if (j == father) continue;
dfs1(j, u, depth + 1);
sz[u] += sz[j];
if (sz[j] > sz[son[u]]) son[u] = j;
}
}
void dfs2(int u, int t) {
top[u] = t, id[u] = ++ cnt;
if (son[u]) dfs2(son[u], t);
for (int i = h[u]; i; i = ne[i]) {
int j = e[i];
if (j == fa[u] || j == son[u]) continue;
dfs2(j, j);
}
}
struct Tree {
int l, r;
int add, sum;
}tr[N << 2];
#define ls u << 1
#define rs u << 1 | 1
void pushup(int u) {
tr[u].sum = (tr[ls].sum + tr[rs].sum) % mod;
}
void pushdown(int u) {
if (tr[u].add) {
tr[ls].add += tr[u].add, tr[rs].add += tr[u].add;
(tr[ls].sum += (s[tr[ls].r] - s[tr[ls].l - 1]) * tr[u].add % mod + mod) %= mod;
(tr[rs].sum += (s[tr[rs].r] - s[tr[rs].l - 1]) * tr[u].add % mod + mod) %= mod;
tr[u].add = 0;
}
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if (l == r) return;
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
}
void modify(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) {
tr[u].add += 1, (tr[u].sum += s[tr[u].r] - s[tr[u].l - 1] + mod) %= mod;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(ls, l, r);
if (r > mid) modify(rs, l, r);
pushup(u);
}
int query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1, res = 0;
if (l <= mid) res = query(ls, l, r);
if (r > mid) (res += query(rs, l, r)) %= mod;
return res;
}
void modify_path(int u, int v) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
modify(1, id[top[u]], id[u]);
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
modify(1, id[v], id[u]);
}
int query_path(int u, int v) {
int res = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
(res += query(1, id[top[u]], id[u])) %= mod;
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
(res += query(1, id[v], id[u])) %= mod;
return res;
}
int query_node(int u, int x) {
if (tr[u].l == tr[u].r) return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) return query_node(ls, x);
else return query_node(rs, x);
}
signed main()
{
scanf("%lld%lld%lld", &n, &m, &k);
for (int i = 2; i <= n; i ++ ) {
int father; scanf("%lld", &father);
add(father, i);
}
dfs1(1, 0, 1), dfs2(1, 1), build(1, 1, n);
for (int i = 1; i <= n; i ++ )
nw[i] = (qpow(dep[i], k, mod) - qpow(dep[i] - 1, k, mod) + mod) % mod;
for (int i = 1; i <= n; i ++ )
s[i] = (s[i - 1] + nw[id[i]]) % mod;
for (int i = 1; i <= m; i ++ ) {
scanf("%lld%lld", &q[i].x, &q[i].y);
q[i].id = i;
}
sort(q + 1, q + m + 1);
int iter = 1;
for (int i = 1; i <= m; i ++ ) {
do {
modify_path(1, iter);
iter ++ ;
} while (iter <= q[i].x);
ans[q[i].id] = query_path(1, q[i].y);
}
for (int i = 1; i <= m; i ++ )
printf("%lld\n", ans[i]);
return 0;
}