请求加强数据
查看原帖
请求加强数据
513329
徐晨轩✅楼主2022/7/31 09:25

这份代码中,线段树中没加取模,可以 AC

#include <bits/stdc++.h>
#define int long long
using namespace std;

class SegTree {
	private:
		struct Node {
			int Left, Right, Sum, Delta;
			Node *Lchild, *Rchild;
		};
	public:
		Node *Tree = new Node;
		void build(Node *cur, int L, int R) {
			cur->Left = L;
			cur->Right = R;
			if (L != R) {
				cur->Lchild = new Node;
				cur->Rchild = new Node;
				cur->Sum = 0;
				build(cur->Lchild, L, (L + R) >> 1);
				build(cur->Rchild, ((L + R) >> 1) + 1, R);
			} else {
				cur->Lchild = cur->Rchild = NULL;
				cur->Sum = 0;
			};
		}
		int query(Node *cur, int L, int R) {
			int ans = 0;
			if (L <= cur->Left && cur->Right <= R)
				ans += cur->Sum + cur->Delta * (cur->Right - cur->Left + 1);
			else {
				cur->Lchild->Delta += cur->Delta;
				cur->Rchild->Delta += cur->Delta;
				cur->Delta = 0;
				if (L <= (cur->Left + cur->Right) >> 1)
					ans += query(cur->Lchild, L, R);
				if (R > (cur->Left + cur->Right) >> 1)
					ans += query(cur->Rchild, L, R);
				cur->Sum = cur->Lchild->Sum + cur->Lchild->Delta * (cur->Lchild->Right - cur->Lchild->Left + 1) + cur->Rchild->Sum + cur->Rchild->Delta * (cur->Rchild->Right - cur->Rchild->Left + 1);;
			}
			return ans;
		}
		void update(Node *cur, int Dex, int Change) {
			if (cur->Left == cur->Right) {
				cur->Sum = Change;
				cur->Delta = 0;
			} else {
				cur->Lchild->Delta += cur->Delta;
				cur->Rchild->Delta += cur->Delta;
				cur->Delta = 0;
				if (Dex <= (cur->Left + cur->Right) >> 1)update(cur->Lchild, Dex, Change);
				if (Dex > (cur->Left + cur->Right) >> 1)update(cur->Rchild, Dex, Change);
				cur->Sum = cur->Lchild->Sum + cur->Lchild->Delta * (cur->Lchild->Right - cur->Lchild->Left + 1) + cur->Rchild->Sum + cur->Rchild->Delta * (cur->Rchild->Right - cur->Rchild->Left + 1);
			}
		}
		void secupdate(Node *cur, int L, int R, int Change) {
			if (L <= cur->Left && cur->Right <= R)
				cur->Delta += Change;
			else {
				if (L <= (cur->Left + cur->Right) >> 1)secupdate(cur->Lchild, L, R, Change);
				if (R > (cur->Left + cur->Right) >> 1)secupdate(cur->Rchild, L, R, Change);
				cur->Sum = cur->Lchild->Sum + cur->Lchild->Delta * (cur->Lchild->Right - cur->Lchild->Left + 1) + cur->Rchild->Sum + cur->Rchild->Delta * (cur->Rchild->Right - cur->Rchild->Left + 1);
			}
		}
};

const int N = 100001;
int n, q, root, mod, v[N];
int cnt, size[N], dep[N], fa[N], son[N], top[N], id[N], rk[N];
vector<int> g[N];
SegTree S;

void dfs1(int u, int f) {
//	cout << "dfs1(" << u << ", " << f << ")" << endl;
	size[u] = 1;
	dep[u] = dep[fa[u]] + 1;
	for (int v: g[u]) {
//		cout << v << " ";
//		cout << "# " << v << endl;
		if (v == f) continue;
		fa[v] = u;
		dfs1(v, u);
		size[u] += size[v];
		if (size[son[u]] < size[v])
			son[u] = v;
	}
//	cout << endl;
}

void dfs2(int u, int f, int tp) {
	top[u] = tp;
	id[u] = ++cnt;
	rk[cnt] = u;
	if (son[u]) dfs2(son[u], u, tp);
	for (int v: g[u])
		if (v != f && v != son[u])
			dfs2(v, u, v);
}

void op1(int x, int y, int k) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		S.secupdate(S.Tree, id[top[x]], id[x], k);
		x = fa[top[x]];
	}
	if (id[x] > id[y]) swap(x, y);
	S.secupdate(S.Tree, id[x], id[y], k);
}

int op2(int x, int y) {
	int ret = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		(ret += S.query(S.Tree, id[top[x]], id[x])) %= mod;
		x = fa[top[x]];
	}
	if (id[x] > id[y]) swap(x, y);
	return (ret + S.query(S.Tree, id[x], id[y])) % mod;
}

signed main() {
	cin >> n >> q >> root >> mod;
	for (int i = 1; i <= n; i++)
		cin >> v[i];
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
//	for (int i = 1; i < n; i++) {
//		cout << i << ": ";
//		for (int j: g[i])
//			cout << j << " ";
//		cout << endl;
//	}
	dfs1(root, -1);
	dfs2(root, -1, root);
//	for (int i = 1; i <= n; i++)
//		cout << fa[i] << " ";
//	cout << endl;
//	for (int i = 1; i <= n; i++)
//		cout << dep[i] << " ";
//	cout << endl; 
//	for (int i = 1; i <= n; i++)
//		cout << top[i] << " ";
//	cout << endl;
//	for (int i = 1; i <= n; i++)
//		cout << id[i] << " ";
//	cout << endl;
//	for (int i = 1; i <= n; i++)
//		cout << size[i] << " ";
//	cout << endl;
	S.build(S.Tree, 1, n);
	for (int i = 1; i <= n; i++)
		S.update(S.Tree, i, v[rk[i]]);
	while (q--) {
		int op;
		cin >> op;
		if (op == 1) {
			int x, y, k;
			cin >> x >> y >> k;
			op1(x, y, k);
		} else if (op == 2) {
			int x, y;
			cin >> x >> y;
			cout << op2(x, y) << endl;
		} else if (op == 3) {
			int x, y;
			cin >> x >> y;
			S.secupdate(S.Tree, id[x], id[x] + size[x] - 1, y);
		} else if (op == 4) {
			int x;
			cin >> x;
			cout << S.query(S.Tree, id[x], id[x] + size[x] - 1) % mod << endl;
		}
	}
	return 0;
}
2022/7/31 09:25
加载中...