30pts求调
查看原帖
30pts求调
573963
wbh20090611楼主2024/7/11 09:18

WA30pts

#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
#define int long long
#define INT_MIN LONG_LONG_MIN
using namespace std;
const int N = 30010;
class p
{
	public:
		int first, second;
};
vector <int> e[N];
int top[N], dep[N], son[N], size[N], f[N];
int sum[N << 3], dfn[N], lll, maxn[N << 3], tag[N << 3];
int n, val[N], m, a, b, c;
char s[100010];
void build(int root, int l, int r)
{
	if (l == r)
	{
		sum[root] = val[dfn[l]];
		maxn[root] = val[dfn[l]];
		return;
	}
	build(root << 1, l, mid);
	build((root << 1) + 1, mid + 1, r);
	maxn[root] = max(maxn[root << 1], maxn[(root << 1) + 1]);
	sum[root] = sum[root << 1] + sum[(root << 1) + 1];
	return;
}
void update(int root, int l, int r, int x, int k)
{
	if(l == r)
	{
		sum[root] = k;
		maxn[root] = k;
		return;
	}
	if (x > mid)
		update((root << 1) + 1, mid + 1, r, x, k);
	else
		update(root << 1, l, mid, x, k);
	maxn[root] = max(maxn[root << 1], maxn[(root << 1) + 1]);
	sum[root] = sum[root << 1] + sum[(root << 1) + 1];
	return;
}
p query(int root, int l, int r, int qx, int qy)
{
	if (qx > qy)
		swap(qx ,qy);
	if (l >= qx && r <= qy)
		return {sum[root], maxn[root]};
	if (l == r)
		return {0, INT_MIN};
	p u = {0, INT_MIN}, v = {0, INT_MIN};
	if (mid >= qx)
		u = query(root << 1, l, mid, qx, qy);
	if (qy > mid)
		v = query((root << 1) + 1, mid + 1, r, qx, qy);
	return {u.first + v.first, max(u.second, v.second)};
}
void dfs1(int x, int fa)
{
	f[x] = fa;
	dep[x] = dep[fa] + 1;
	size[x] = 1;
	for (auto i : e[x])
	{
		if (i == fa)
			continue;
		dfs1(i, x);
		size[x] += size[i];
		if(size[son[x]] < size[i])
			son[x] = i;
	}
	return;
}
void dfs2(int x, int t)
{
	dfn[x] = ++lll;
	top[x] = t;
	if (!son[x])
		return;
	dfs2(son[x], t);
	for(auto i : e[x])
	{
		if (i == f[x] || i == son[x])
			continue;
		dfs2(i, i);
	}
}
int query_max(int x, int y)
{
	int ans = INT_MIN;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		ans = max(ans, query(1, 1, n, dfn[top[x]], dfn[x]).second);
		x = f[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	ans = max(ans, query(1, 1, n, dfn[x], dfn[y]).second);
	return ans;
}
int query_sum(int x, int y)
{
	int ans = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		ans += query(1, 1, n, dfn[top[x]], dfn[x]).first;
		x = f[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	ans += query(1, 1, n, dfn[x], dfn[y]).first;
	return ans;
}
signed main()
{
	cin >> n;
	for (int i = 1, u, v; i < n; i++)
	{
		scanf("%lld%lld", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i = 1; i <= n; i++)
		scanf("%lld", val + i);
	f[1] = 1;
	dep[1] = 1;
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	cin >> m;
	while (m--)
	{
		scanf("%s%lld%lld", s, &a, &b);
		if (s[1] == 'M')
		{
			if (dep[a] > dep[b])
			{
				swap(a, b);
			}
			cout << query_max(a, b) << "\n";
		}
		else if (s[1] == 'S')
		{
			if (dep[a] > dep[b])
			{
				swap(a, b);
			}
			cout << query_sum(a, b) << "\n";
		}
		else
		{
			update(1, 1, n, dfn[a], b);
		}
	}
}
2024/7/11 09:18
加载中...