树链剖分,全 RE,求助
查看原帖
树链剖分,全 RE,求助
246014
Cutest_Junior楼主2021/4/7 16:35
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 1e5 + 5;

int a[N];

vector<int> edge[N];

void add(int u, int v) {
	edge[u].push_back(v);
}

int father[N];
int son[N];
int size[N];
int dep[N];

void dfs1(int x) {
	size[x] = 1;
	for (int i = 0; i < (int)edge[x].size(); ++i) {
		int to = edge[x][i];
		if (to == father[x]) {
			continue;
		}
		father[to] = x;
		dep[to] = dep[x] + 1;
		dfs1(to);
		size[x] += size[to];
		if (size[to] > size[son[x]]) {
			son[x] = to;
		}
	}
}

int top[N];
int id[N], idtot;

void dfs2(int x, int t) {
	top[x] = t;
	id[x] = ++idtot;
	if (son[x]) {
		dfs2(son[x], t);
	}
	for (int i = 0; i < (int)edge[x].size(); ++i) {
		int to = edge[x][i];
		if (to == father[x] || to == son[x]) {
			continue;
		}
		dfs2(to, to);
	}
}

struct Tree {
	Tree *ls, *rs;
	int left, cnt, right, lazy;
	
	Tree() {
		left = cnt = right = lazy = 0;
	}
	
	void update(int k) {
		left = right = k;
		cnt = 0;
	}
	
	void merge(Tree t1, Tree t2) {
		cnt = t1.cnt + t2.cnt + ((t1.right != t2.left) && t1.right && t2.left);
		left = t1.left ? t1.left : t2.left;
		right = t2.right ? t2.right : t1.right;
	}
} seg[N + N], *root = seg;
int tot;

void build(Tree *t, int l, int r) {
	if (l == r) {
		return;
	}
	int mid = (l + r) >> 1;
	t->ls = &seg[++tot];
	t->rs = &seg[++tot];
	build(t->ls, l, mid);
	build(t->rs, mid + 1, r);
}

void pushdown(Tree *t) {
	if (!t->lazy) {
		return;
	}
	t->ls->update(t->lazy);
	t->rs->update(t->lazy);
	t->lazy = 0;
}

void change(Tree *t, int l, int r, int x, int y, int k) {
	if (x <= l && r <= y) {
		t->update(k);
		return;
	}
	pushdown(t);
	int mid = (l + r) >> 1;
	if (x <= mid) {
		change(t->ls, l, mid, x, y, k);
	}
	if (mid < y) {
		change(t->rs, mid + 1, r, x, y, k);
	}
	t->merge(*t->ls, *t->rs);
}

Tree query(Tree *t, int l, int r, int x, int y) {
	if (x <= l && r <= y) {
		return *t;
	}
	pushdown(t);
	int mid = (l + r) >> 1;
	Tree ans;
	if (x <= mid) {
		ans.merge(ans, query(t->ls, l, mid, x, y));
	}
	if (mid < y) {
		ans.merge(ans, query(t->rs, mid + 1, r, x, y));
	}
	return ans;
}

int n;

void treechange(int x, int y, int k) {
	while (top[x] != top[y]) {
		if (dep[x] < dep[y]) {
			swap(x, y);
		}
		change(root, 1, n, id[top[x]], id[x], k);
		x = father[top[x]];
	}
	if (dep[x] < dep[y]) {
		swap(x, y);
	}
	change(root, 1, n, id[y], id[x], k);
}

int treequery(int x, int y) {
//	printf("fuc");
	Tree ans1, ans2;
	while (top[x] != top[y]) {
//		printf("%d %d\n", x, y);
		if (dep[x] < dep[y]) {
			ans2.merge(query(root, 1, n, id[top[y]], id[y]), ans2);
			y = father[top[y]];
		}
		else {
			ans1.merge(query(root, 1, n, id[top[x]], id[x]), ans1);
			x = father[top[x]];
		}
	}
	if (dep[x] < dep[y]) {
		Tree t = query(root, 1, n, id[x], id[y]);
		swap(ans1.left, ans1.right);
		t.merge(ans1, t);
		t.merge(t, ans2);
		return t.cnt;
	}
	else {
		Tree t = query(root, 1, n, id[y], id[x]);
		swap(ans2.left, ans2.right);
		t.merge(ans1, t);
		t.merge(t, ans2);
		return t.cnt;
	}
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
	}
	for (int i = 1; i < n; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v);
		add(v, u);
	}
	dfs1(1);
	dfs2(1, 1);
	build(root, 1, n);
	for (int i = 1; i <= n; ++i) {
		change(root, 1, n, id[i], id[i], a[i]);
	}
	for (int i = 1; i <= m; ++i) {
		char s[5];
		int x, y, k;
//		printf("%d ", i);
		scanf("%s%d%d", s, &x, &y);
//		printf("%d %d\n", x, y);
		if (s[0] == 'C') {
			scanf("%d", &k);
			treechange(x, y, k);
		}
		else {
			printf("%d\n", treequery(x, y) + 1);
		}
	}
}
2021/4/7 16:35
加载中...