树剖20pts求调,只过了样例和56测试点
查看原帖
树剖20pts求调,只过了样例和56测试点
564415
huyuun楼主2023/1/15 22:19
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>

using namespace std;

template <typename T>
inline void read(T &x)
{
	T f = 0;
	x = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-') x = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		f = (f << 3) + (f << 1) + (c ^ 48);
		c = getchar();
	}
	x *= f;
}

typedef long long LL;

const int N = 3e4 + 10, M = N << 1;
const LL INF = 1e18;

int n, q, w[N];
int h[N], ne[M], e[M], idx;
int dep[N], fa[N], nw[N], id[N], sz[N], top[N], son[N], cnt;
struct SegmentTree
{
	int l, r;
	LL v, sum;
}tr[N << 2];

void add(int a, int b)
{
	e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
}

void dfs1(int u, int father, int depth)
{
	sz[u] = 1, fa[u] = father, dep[u] = depth;
	for(int i = h[u] ; i ; i = ne[i])
	{
		int j = e[i];
		if(j == father) continue;
		dfs1(j, u, depth + 1);
		sz[u] += sz[j];
		if(sz[son[u]] < sz[j]) son[u] = j;
	}
}

void dfs2(int u, int t)
{
	id[u] = ++ cnt, top[u] = t, nw[id[u]] = w[u];
	if(!son[u]) return;
	dfs2(son[u], t);
	for(int i = h[u] ; i ; i = ne[i])
	{
		int j = e[i];
		if(j == fa[u] || j == son[u]) continue;
		dfs2(j, j);
	}
}

void pushup(int u)
{
	tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);
	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

void build(int u, int l, int r)
{
	tr[u] = {l, r, (LL)nw[r], (LL)nw[r]};
	if(l == r) return;
	int mid = l + r >> 1;
	build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
	pushup(u);
}

void modify(int u, int k, int x)
{
	if(tr[u].l == tr[u].r && tr[u].l == k)
	{
		tr[u].sum = tr[u].v = (LL)x;
		return;
	}
	
	int mid = tr[u].l + tr[u].r >> 1;
	if(mid >= k) modify(u << 1, k, x);
	else modify(u << 1 | 1, k, x);
	pushup(u); 
}

LL query(int u, int l, int r, int type)
{
	if(tr[u].l >= l && tr[u].r <= r) return type ? tr[u].sum : tr[u].v;
	int mid = tr[u].l + tr[u].r >> 1;
	LL v = type ? 0 : -INF;
	if(mid >= l) v = type ? (v + query(u << 1, l, r, type)) : max(v, query(u << 1, l, r, type));
	if(mid < r) v = type ? (v + query(u << 1 | 1, l, r, type)) : max(v, query(u << 1 | 1, l, r, type));
	return v;
}

LL query_max(int u, int v)
{
	LL res = -INF;
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		res = max(res, query(1, id[top[u]], id[u], 0));
		u = fa[top[u]];
	}
	
	if(dep[u] < dep[v]) swap(u, v);
	res = max(res, query(1, id[v], id[u], 0));
	return res;
}

LL query_sum(int u, int v)
{
	LL res = 0;
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		res += query(1, id[top[u]], id[u], 1);
		u = fa[top[u]];
	}
	
	if(dep[u] < dep[v]) swap(u, v);
	res += query(1, id[v], id[u], 1);
	return res;
}

int main()
{
	read(n);
	for(int i = 1 ; i < n ; i ++ )
	{
		int a, b;
		read(a), read(b);
		add(a, b), add(b, a);
	}
	
	for(int i = 1 ; i <= n ; i ++ ) read(w[i]);
	dfs1(1, -1, 1);
	dfs2(1, 1);
	build(1, 1, n);
	
	read(q);
	while(q -- )
	{
		char op[10];
		int u, v;
		scanf("%s", op), read(u), read(v);
		if(!strcmp(op, "CHANGE")) modify(1, u, v);
		else if(!strcmp(op, "QMAX")) printf("%lld\n", query_max(u, v));
		else printf("%lld\n", query_sum(u, v));
	}
	
	return 0;
}
2023/1/15 22:19
加载中...