有没有路过巨神帮忙康康
查看原帖
有没有路过巨神帮忙康康
519384
Link_Cut_Y楼主2022/10/3 22:36

样例过了,但是全 WA\texttt{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;
}
2022/10/3 22:36
加载中...