树剖TLE70求调
查看原帖
树剖TLE70求调
384381
agosto楼主2023/2/25 13:43
#include<iostream>
#include<vector>
using namespace std;
#define mid ((l+r)/2)
#define ls rt*2,l,mid
#define rs rt*2+1,mid+1,r
const int maxn = 1e6 + 5;
vector<int>g[maxn];
int n, m;
struct node {
	int l, r, s;
};
node tree[maxn];
node merge(node a, node b) {
	node c;
	c.s = a.s + b.s;
	if (b.l == a.r) {
		c.s--;
	}
	c.l = a.l;
	c.r = b.r;
	return c;
}
int tot, tag[maxn], w[maxn], idx[maxn], fa[maxn], depth[maxn], len[maxn], son[maxn], topf[maxn];
bool ftag[maxn], used[maxn];
void pushdown(int rt, int l, int r) {
	if (ftag[rt] == 0) {
		return;
	}
	tree[rt].l = tag[rt];
	tree[rt].r = tag[rt];
	tree[rt].s = 1;
	tag[rt * 2] = tag[rt];
	tag[rt * 2 + 1] = tag[rt];
	tag[rt] = 0;
	ftag[rt * 2] = 1;
	ftag[rt * 2 + 1] = 1;
	ftag[rt] = 0;
}
void pushup(int rt, int l, int r) {
	pushdown(rt, l, r);
	pushdown(ls);
	pushdown(rs);
	tree[rt] = merge(tree[rt * 2], tree[rt * 2 + 1]);
}
void update(int rt, int l, int r, int L, int R, int v) {
	pushdown(rt, l, r);
	if (L <= l && r <= R) {
		ftag[rt] = 1;
		tag[rt] = v;
		return;
	}
	if (L <= mid) {
		update(ls, L, R, v);
	}
	if (R > mid) {
		update(rs, L, R, v);
	}
	pushup(rt, l, r);
}
node query(int rt, int l, int r, int L, int R) {
	pushdown(rt, l, r);
	if (L <= l && r <= R) {
		return tree[rt];
	} else if (L > mid) {
		return query(rs, L, R);
	} else if (R <= mid) {
		return query(ls, L, R);
	} else {
		return merge(query(ls, L, R), query(rs, L, R));
	}
}
void updaterange(int x, int y, int z) {
	while (topf[x] != topf[y]) {
		int fx = topf[x], fy = topf[y];
		if (depth[fx] < depth[fy]) {
			swap(fx, fy);
			swap(x, y);
		}
		update(1, 1, n, idx[fx], idx[x], z);
		x = fa[fx];
	}
	if (depth[x] < depth[y]) {
		swap(x, y);
	}
	update(1, 1, n, idx[y], idx[x], z);
}
int queryrange(int x, int y) {
	int ans = 0, las, lst;
	las = lst = -1;
	while (topf[x] != topf[y]) {
		int fx = topf[x], fy = topf[y];
		if (depth[fx] < depth[fy]) {
			swap(fx, fy);
			swap(x, y);
			swap(las, lst);
		}
		node t = query(1, 1, n, idx[fx], idx[x]);
		ans += t.s;
		if (t.r == las) {
			ans--;
		}
		las = t.l;
		x = fa[fx];
	}
	if (depth[x] < depth[y]) {
		swap(x, y);
		swap(las, lst);
	}
	node t = query(1, 1, n, idx[y], idx[x]);
	ans += t.s;
	if (t.r == las) {
		ans--;
	}
	if (t.l == lst) {
		ans--;
	}
	return ans;
}
void dfs1(int u, int f, int deep) {
	depth[u] = deep;
	fa[u] = f;
	len[u] = 1;
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (f == v) {
			continue;
		}
		dfs1(v, u, deep + 1);
		len[u] += len[v];
		if (len[son[u] < len[v]]) {
			son[u] = v;
		}
	}
}
void dfs2(int u, int f) {
	if (u == 0) {
		return;
	}
	topf[u] = f;
	used[u] = 1;
	idx[u] = ++tot;
	dfs2(son[u], f);
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (used[v] != 0) {
			continue;
		}
		dfs2(v, v);
	}

}
int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> w[i];
	}
	for (int i = 1; i <= n - 1; i++) {
		int u, v;
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1, 0, 1);
	dfs2(1, 1);
	for (int i = 1; i <= n; i++) {
		update(1, 1, n, idx[i], idx[i], w[i]);
	}
	for (int i = 1; i <= m; i++) {
		char x;
		int a, b, c;
		cin >> x;
		if (x == 'C') {
			cin >> a >> b >> c;
			updaterange(a, b, c);
		} else {
			cin >> a >> b;
			cout << queryrange(a, b) << endl;
		}
	}
	return 0;
}
2023/2/25 13:43
加载中...