Homework Introduction

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, m, dep[N], son[N], fa[N], siz[N], P;
int top[N], id[N], w[N], wt[N], tot, rt;
int tree[N << 2], tag[N << 2];
vector<int>e[N];

void dfs1(int x, int f, int deep) {
	dep[x] = deep;
	fa[x] = f;
	siz[x] = 1;
	int maxx = 0;
	for (auto v : e[x]) {
		if (v == f)
			continue;
		dfs1(v, x, deep + 1);
		siz[x] += siz[v];
		if (siz[v] > maxx) {
			maxx = siz[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topfa) {
	top[x] = topfa;
	id[x] = ++tot;
	wt[tot] = w[x];
	if (!son[x])
		return;
	dfs2(son[x], topfa);
	for (auto v : e[x]) {
		if (v == fa[x] || v == son[x])
			continue;
		dfs2(v, v);
	}
}

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
	tree[rt] %= P;
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1] %= P;
		tag[rt << 1 | 1] += tag[rt];
		tag[rt << 1 | 1] %= P;
		int mid = (l + r) >> 1;
		tree[rt << 1] += tag[rt] * (mid - l + 1);
		tree[rt << 1] %= P;
		tree[rt << 1 | 1] += tag[rt] * (r - mid);
		tree[rt << 1 | 1] %= P;
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = wt[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tag[rt] += c;
		tree[rt] += c * (r - l + 1);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(l, r, rt);
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

int query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	pushdown(l, r, rt);
	int mid = (l + r) >> 1;
	int sum = 0;
	if (L <= mid)
		sum += query(l, mid, rt << 1, L, R), sum %= P;
	if (R > mid)
		sum += query(mid + 1, r, rt << 1 | 1, L, R), sum %= P;
	return sum;
}

void pos1(int x, int y, int z) {
	z %= P;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		update(1, n, 1, id[top[x]], id[x], z);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, n, 1, id[x], id[y], z);
}

int pos2(int x, int y) {
	int res = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] > dep[top[y]])
			swap(x, y);
		res += query(1, n, 1, id[top[y]], id[y]);
		res %= P;
		y = fa[top[y]];
	}
	if (dep[x] < dep[y])
		swap(x, y);
	res += query(1, n, 1, id[y], id[x]);
	res %= P;
	return res;
}

void pos3(int x, int z) {
	z %= P;
	update(1, n, 1, id[x], id[x] + siz[x] - 1, z);
}

int pos4(int x) {
	return query(1, n, 1, id[x], id[x] + siz[x] - 1) % P;
}

signed main() {
	cin >> n >> m >> rt >> P;
	for (int i = 1; i <= n; i++) {
		cin >> w[i];
	}
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(rt, 0, 1);
	dfs2(rt, rt);
	build(1, n, 1);
	for (int i = 1; i <= m; i++) {
		int pos, x, y, z;
		cin >> pos;
		if (pos == 1) {
			cin >> x >> y >> z;
			pos1(x, y, z);
		} else if (pos == 2) {
			cin >> x >> y;
			cout << pos2(x, y) << endl;
		} else if (pos == 3) {
			cin >> x >> z;
			pos3(x, z);
		} else if (pos == 4) {
			cin >> x;
			cout << pos4(x) << endl;
		}
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, m, dep[N], son[N], fa[N], siz[N], P;
int top[N], id[N], w[N], wt[N], tot, rt;
int tree[N << 2], tag[N << 2];
vector<int>e[N];

void dfs1(int x, int f, int deep) {
	dep[x] = deep;
	fa[x] = f;
	siz[x] = 1;
	int maxx = 0;
	for (auto v : e[x]) {
		if (v == f)
			continue;
		dfs1(v, x, deep + 1);
		siz[x] += siz[v];
		if (siz[v] > maxx) {
			maxx = siz[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topfa) {
	top[x] = topfa;
	id[x] = ++tot;
	wt[tot] = w[x];
	if (!son[x])
		return;
	dfs2(son[x], topfa);
	for (auto v : e[x]) {
		if (v == fa[x] || v == son[x])
			continue;
		dfs2(v, v);
	}
}

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1 | 1] += tag[rt];
		int mid = (l + r) >> 1;
		tree[rt << 1] += tag[rt] * (mid - l + 1);
		tree[rt << 1 | 1] += tag[rt] * (r - mid);
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = wt[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tag[rt] += c;
		tree[rt] += c * (r - l + 1);
		return;
	}
	pushdown(l, r, rt);
	int mid = (l + r) >> 1;
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

int query(int l, int r, int rt, int p) {
	if (l == r) {
		return tree[rt];
	}
	pushdown(l, r, rt);
	int mid = (l + r) >> 1;
	if (p <= mid)
		return query(l, mid, rt << 1, p);
	else
		return query(mid + 1, r, rt << 1 | 1, p);
}

void pos1(int x, int y) {
	while (top[x] != top[y]) {
		if (dep[top[x]] > dep[top[y]])
			swap(x, y);
		update(1, n, 1, id[top[y]], id[y], 1);
		y = fa[top[y]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	if (x != y) {
		update(1, n, 1, id[x] + 1, id[y], 1);
	}
}

int pos2(int x, int y) {
	if (dep[y] > dep[x])
		return query(1, n, 1, id[y]);
	else
		return query(1, n, 1, id[x]);
}

signed main() {
	cin >> n >> m;
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(1, 0, 1);
	dfs2(1, 1);
	build(1, n, 1);
	while (m--) {
		char pos;
		int x, y;
		cin >> pos >> x >> y;
		if (pos == 'P') {
			pos1(x, y);
		} else
			cout << pos2(x, y) << endl;
	}
	return 0;
}

Problem

Please claim the assignment to see the problems.
Status
Live...
Problem
18
Open Since
2025-8-14 12:00
Deadline
2025-11-30 23:59
Extension
24 hour(s)