萌新初学OI求助树剖
查看原帖
萌新初学OI求助树剖
246019
Elma_楼主2020/8/11 14:17

rt,样例过了然而抱灵了/kk

然后这题还不给数据,代码感觉非常对不知道哪里写挂了……有神仙看看吗/kel

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define maxn 10000005
using namespace std;

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

struct segment { ll max, sum; } tree[maxn << 2];
struct node { ll to, nxt; } edge[maxn];
ll n, q, dfs_block, tot, res;
ll head[maxn], val[maxn], a[maxn];
ll son[maxn], dfn[maxn], fa[maxn], dep[maxn], siz[maxn], top[maxn];

inline ll lson(ll x) { return x << 1; }
inline ll rson(ll x) { return x << 1 | 1; }
inline void push_up(ll x)
{
	tree[x].sum = tree[lson(x)].sum + tree[rson(x)].sum;
	tree[x].max = max(tree[lson(x)].max, tree[rson(x)].max);
}
inline void add(int u, int v)
{
	edge[++tot].nxt = head[u];
	edge[tot].to = v;
	head[u] = tot;
}
inline void addedge(int u, int v)
{
	add(u, v), add(v, u);
}

void build(ll x, ll l, ll r)
{
	if (l == r)
	{
		tree[x].sum = tree[x].max = a[l];
		return;
	}
	ll mid = (l + r) >> 1;
	build(lson(x), l, mid);
	build(rson(x), mid + 1, r);
	push_up(x);
}

void modify(ll x, ll l, ll r, ll to, ll k)
{
	if (l == r)
	{
		tree[x].sum = tree[x].max = k;
		return;	
	}
	ll mid = (l + r) >> 1;
	if (to <= mid) modify(lson(x), l, mid, to, k);
	if (to > mid) modify(rson(x), mid + 1, r, to, k);
	push_up(x);
}

ll query_max(ll x, ll l, ll r, ll L, ll R)
{
	if (l >= L && r <= R) return tree[x].max;
	ll mid = (l + r) >> 1, ans = -1;
	if (mid >= L) ans = max(ans, query_max(lson(x), l, mid, L, R));
	if (mid < R) ans = max(ans, query_max(rson(x), mid + 1, r, L, R));
	return ans;
}

ll query_sum(ll x, ll l, ll r, ll L, ll R)
{
	if (l >= L && r <= R) return tree[x].sum;
	ll mid = (l + r) >> 1, res = 0;
	if (mid >= L) res += query_sum(lson(x), l, mid, L, R);
	if (mid < R) res += query_sum(rson(x), mid + 1, r, L, R);
	return res;
}

void dfs1(int u, int fath)
{
	siz[u] = 1, dep[u] = dep[fath] + 1;
	fa[u] = fath, son[u] = 0;
	for (int i = head[u];i;i = edge[i].nxt)
	{
		int v = edge[i].to;
		if (v == fath) continue;
		dfs1(v, u);siz[u] += siz[v];
		if (siz[v] > siz[son[u]])
			son[u] = v;
	}
}

void dfs2(int u)
{
	dfn[u] = ++dfs_block, a[dfs_block] = val[u];
	if (u == son[fa[u]]) top[u] = top[fa[u]];
	else top[u] = u;
	if (son[u]) dfs2(son[u]);
	for (int i = head[u];i;i = edge[i].nxt)
	{
		int v = edge[i].to;
		if (v != fa[u] && v != son[u]) dfs2(v);
	}
}

ll query_max_chain(int x, int y)
{
	ll res = -1;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		res = max(res, query_max(1, 1, n, dfn[top[x]], dfn[x]));
		x = fa[top[x]];
	}
	if (dep[x] < dep[y]) swap(x, y);
	res = max(res, query_max(1, 1, n, dfn[y], dfn[x]));
	return res;
}

ll query_sum_chain(int x, int y)
{
	ll res = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		res += query_sum(1, 1, n, dfn[top[x]], dfn[x]);
		x = fa[top[x]];
	}
	if (dep[x] < dep[y]) swap(x, y);
	res += query_sum(1, 1, n, dfn[y], dfn[x]);
	return res;
}

int main(void)
{
	n = read();
	for (int i = 1;i < n;i++)
	{
		int u = read(), v = read();
		addedge(u, v);
	}
	for (int i = 1;i <= n;i++)
		val[i] = read();
	dfs1(1, 0), dfs2(1), build(1, 1, n);
	q = read();
	while (q--)
	{
		string opt;
		cin >> opt;
		if (opt[1] == 'H')
		{
			int u = read(), t = read();
			modify(1, 1, n, u, t);
		}
		else if (opt[1] == 'M')
		{
			int u = read(), v = read();
			printf("%lld\n", query_max_chain(u, v));
		}
		else if (opt[1] == 'S')
		{
			int u = read(), v = read();
			printf("%lld\n", query_sum_chain(u, v));
		}
	}
	return 0;
}
2020/8/11 14:17
加载中...