求助
查看原帖
求助
716011
封禁用户楼主2022/5/2 12:43
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100000 + 5; 
int n , q , w[N] , fa[N] , size[N] , dep[N] , son[N] , top[N] , dfn[N] , s[N] , t;
int u , v;
string opt;
vector < int > g[N];
struct Node
{
	int l , r , s , mx;
} tree[N * 4 + 5]; 
void build(int p , int l , int r)
{
	int lc = p << 1 , rc = p << 1 | 1;
	tree[p].l = l , tree[p].r = r;
	if(l == r)
	{
		tree[p].s = tree[p].mx = w[dfn[l]];
		return ;
	}
	int mid = (l + r) >> 1;
	build(lc , l , mid);
	build(rc , mid + 1 , r);
	tree[p].s = tree[lc].s + tree[rc].s;
	tree[p].mx = max(tree[lc].mx , tree[rc].mx);
}
void adde(int p , int x , int y)
{
	int lc = p << 1 , rc = p << 1 | 1;
	if(tree[p].l == tree[p].r && tree[p].l == x)
	{
		tree[p].mx = y;
		tree[p].s = y;
		return ;
	}
	int mid = (tree[p].l + tree[p].r) >> 1;
	if(x <= mid) adde(lc , x , y);
	else adde(rc , x , y);
	tree[p].s = tree[lc].s + tree[rc].s;
	tree[p].mx = max(tree[lc].mx , tree[rc].mx);
}
int query_s(int p , int l , int r)
{
	int lc = p << 1 , rc = p << 1 | 1;
	if(tree[p].l >= l && tree[p].r <= r) return tree[p].s;
	int mid = (tree[p].l + tree[p].r) >> 1;
	int res = 0;
	if(l <= mid) res += query_s(lc , l , r  );
	if(r > mid) res += query_s(rc , l , r);
	return res; 
}
int query_mx(int p , int l , int r)
{
	int lc = p << 1 , rc = p << 1 | 1;
	if(tree[p].l >= l && tree[p].r <= r) return tree[p].mx;
	int mid = (tree[p].l + tree[p].r) >> 1;
	int res = -2147483647	;
	if(l <= mid) res = max(res , query_mx(lc , l , r));
	if(r > mid) res = max(res , query_mx(rc , l , r));
	return res; 	
}
void dfs(int u)
{
	size[u] = 1;
	dep[u] = dep[fa[u]] + 1;
	for(int i = 0 ; i < g[u].size() ; ++ i )
	{
		int v = g[u][i];
		if(v == fa[u]) continue;
		fa[v] = u;
		dfs(v);
		size[u] += size[v];
		if(size[v] > size[son[u]]) son[u] = v;	
	}
}
void dfs_top(int u , int tp)
{
	s[u] = ++t;
	dfn[t] = u;
	top[u] = tp;
	if(son[u]) dfs_top(son[u] , tp);
	for(int i = 0 ; i < g[u].size() ; ++ i )
	{
		int v = g[u][i];
		if(v == fa[u] || v == son[u]) continue;
		dfs_top(v , v);
	}
}
int Max(int u , int v)
{
	int fa_u = top[u] , fa_v = top[v];
	int ret = -2147483647;
	while(fa_u != fa_v)
	{
		if(dep[fa_u] < dep[fa_v]) swap(u , v) , swap(fa_u , fa_v);
		ret = max(ret , query_mx(1 , dfn[fa_u] , dfn[u]));
		u = fa[fa_u];
		fa_u = top[u];
	}	 
	if(dep[u] > dep[v]) swap(u , v);
	ret = max(ret , query_mx(1 , dfn[u] , dfn[v]));
	return ret;
} 
int Sum(int u , int v)
{
	int fa_u = top[u] , fa_v = top[v];
	int ret = 0;
	while(fa_u != fa_v)
	{
		if(dep[fa_u] < dep[fa_v]) swap(u , v) , swap(fa_u , fa_v);
		ret += query_s(1 , dfn[fa_u] , dfn[u]);
		u = fa[fa_u];
		fa_u = top[u];
	}	
	if(dep[u] > dep[v]) swap(u , v);
	ret += query_s(1 , dfn[u] , dfn[v]);
	return ret;	
} 
signed main()
{
	cin >> n;
	for(int i = 1 ; i < n ; ++ i )
	{
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	for(int i = 1 ; i <= n ; ++ i ) cin >> w[i];
	cin >> q;
	dfs(1);
	dfs_top(1 , 1);
	build(1 , 1 , t);
	while(q--)
	{
		cin >> opt >> u >> v;
		if(opt == "CHANGE")
		{
			adde(1 , dfn[u] , v);
		}
		else if(opt == "QMAX")
		{
			cout << Max(u , v) << endl;
		}
		else
		{
			cout << Sum(u , v) << endl;
		}
	}
	return 0;
}
//熟练泼粪 = 树链剖分 

wa,只A了三个点

2022/5/2 12:43
加载中...