(玄关求调
  • 板块灌水区
  • 楼主CZ_Yang
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/8/13 11:44
  • 上次更新2024/8/13 14:38:52
查看原帖
(玄关求调
1178154
CZ_Yang楼主2024/8/13 11:44

就这个树链剖分模板, 样例都过不了(

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct TreeNode {
	int l, r, sum, tag;
} tr[N];
int depth[N], fa[N], size[N], son[N], id[N], top[N], nw[N], w[N], cnt;
int n, m, root, mod;
vector<int> edge[N];


/*-----------------------------------------------------------------*/


inline void pushdown (int p) {
	if (tr[p].tag) {
		int l = p << 1 , r = p << 1 | 1;
		tr[l].tag += tr[p].tag;
		tr[r].tag += tr[p].tag;
		tr[l].sum += tr[p].tag * (tr[p].r - tr[p].l + 1) % mod;
		tr[r].sum += tr[p].tag * (tr[p].r - tr[p].l + 1) % mod;
		tr[p].tag = 0;
	}
}

inline void build (int p, int l , int r) {
	tr[p].l = l;
	tr[p].r = r;
	if (l == r) {
		tr[p].sum = nw[l] % mod;
		return ;
	}
	int mid = l + r >> 1;
	build (p << 1, l, mid);
	build (p << 1 | 1, mid + 1, r);
	tr[p].sum = (tr[p << 1].sum + tr[p << 1 | 1].sum) % mod;
}

inline int query (int p, int x, int y) {
	if (x <= tr[p].l && tr[p].r <= y) return tr[p].sum % mod;
	pushdown (p);
	int mid = tr[p].l + tr[p].r >> 1;
	if (x <= mid) return query (p << 1, x, y);
	if (y > mid) return query (p << 1 | 1, x, y);
}

inline void add (int p, int x, int y, int z) {
	z %= mod;
	if (x <= tr[p].l && tr[p].r <= y) {
		tr[p].sum += z * (tr[p].r - tr[p].l + 1) %mod;
		tr[p].tag += z;
		return;
	}
	pushdown (p);
	int mid = tr[p].l + tr[p].r >> 1;
	if (x <= mid) add (p << 1, x, y, z);
	if (y > mid) add (p << 1 | 1, x, y, z);
	tr[p].sum = (tr[p << 1].sum + tr[p << 1 | 1].sum) % mod;
}


/*-----------------------------------------------------------------*/

inline void dfs1 (int u, int fath) {
	fa[u] = fath;
	depth[u] = depth[fath] + 1;
	size[u] = 1;
	for (int i = 0; i < edge[u].size(); i ++) {
		int v = edge[u][i];
		if (v != fath) {
			dfs1 (v, u);
			size[u] += size[v];
			if (size[v] > size[son[u]]) son[u] = v;
		}
	}
}

inline void dfs2 (int u, int t) {
	top[u] = t;
	id[u] = ++ cnt;
	nw[cnt] = w[u];
	if (!son[u]) return;
	dfs2 (son[u], t);
	for (int i = 0; i < edge[u].size(); i ++) {
		int v = edge[u][i];
		if (v != fa[u] && v != son[u]) dfs2 (v, v);
	}
}

inline int Rquery (int x, int y) {
	int ans = 0;
	while (top[x] != top[y]) {
		if (depth[top[x]] < depth[top[y]]) swap (x, y);
		ans += query (1, id[top[x]], id[x]);
		x = fa[top[x]];
	}
	if (depth[x] > depth[y]) swap (x, y);
	return (ans + query (1, id[x], id[y])) % mod;
}

inline void Radd (int x, int y, int z) {
	z %= mod;
	while (top[x] != top[y]) {
		if (depth[top[x]] < depth[top[y]]) swap (x, y);
		add (1, id[top[x]], id[x], z);
		x = fa[top[x]];
	}
	if (depth[x] > depth[y]) swap (x, y);
	add (1, id[x], id[y], z);
}

inline int Squery (int p) {
	int ans = 0;
	ans += query (1, id[p], id[p] + size[p] - 1);
	return ans;
}

inline void Sadd (int p, int k) {
	add (1, id[p], id[p] + size[p] - 1, k);
}


/*-----------------------------------------------------------------*/


inline int read () {
	int x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
	while (c >= '0' && c <= '9') { x = x * 10 + c - 48; c = getchar(); }
	return x * f;
}

int main() {
	n = read(); m = read(); root = read(); mod = read();
	for (int i = 1; i <= n; i ++) w[i] = read();
	for (int i = 1; i < n; i ++) {
		int a, b;
		a = read(); b = read();
		edge[a].push_back(b);
		edge[b].push_back(a);
	}
	dfs1 (root , 0);
	dfs2 (root , root);
	build (1, 1, n);
	int opt, x, y, z;
	for (int i = 1; i <= n; i ++) cout << id[i] << ' ';
	cout << '\n';
	for (int i = 1; i <= n; i ++) cout << nw[i] << ' ';
	cout << '\n';
	for (int i = 1; i <= m; i ++) {
		opt = read();
		if (opt == 1) {
			x = read(); y = read(); z = read();
			Radd (x, y, z);
		} else if (opt == 2) {
			x = read(); y = read();
			printf ("%d\n", Rquery (x, y));
		} else if (opt == 3) {
			x = read(); y = read();
			Sadd (x, y);
		} else if (opt == 4) {
			x = read();
			printf ("%d\n", Squery (x));
		}
	}
	return 0;
}

啊啊啊这东西是谁发明的

2024/8/13 11:44
加载中...