树剖 20 pts 求调,AC #5, #6, 其他全 WA
查看原帖
树剖 20 pts 求调,AC #5, #6, 其他全 WA
448881
PTqwq楼主2023/3/19 21:38
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
const int N = 3e4 + 5;
int head[N], n, val[N];
struct edge {
	int to, nxt;
} ed[N << 1];
int cnt;
inline void add_edge (int u, int v) {
	cnt ++;
	ed[cnt].to = v;
	ed[cnt].nxt = head[u];
	head[u] = cnt;
}
int son[N], siz[N], depth[N], fa[N], top[N], dfn[N], rk[N];
inline void dfs1 (int u) {
	son[u] = -1;
	siz[u] = 1;
	for (int i = head[u]; i ; i = ed[i].nxt) {
		if (!depth[ed[i].to]) {
			depth[ed[i].to] = depth[u] + 1;
			fa[ed[i].to] = u;
			dfs1 (ed[i].to);
			siz[u] += siz[ed[i].to];
			if (son[u] == -1 || siz[ed[i].to] > siz[son[u]]) son[u] = ed[i].to; 
		}
	}
}
int tmd;
inline void dfs2 (int u, int ck) {
	top[u] = ck;
	tmd ++;
	dfn[u] = tmd;
	rk[tmd] = u;
	if (son[u] == -1) return ;
	dfs2 (son[u], ck);
	for (int i = head[u]; i ; i = ed[i].nxt) {
		if (ed[i].to != son[u] && ed[i].to != fa[u]) dfs2 (ed[i].to, ed[i].to);
	}
}
struct segment_tree {
	int sum[N << 2], mx[N << 2], inc[N << 2];
	inline void push_up (int u) {
		sum[u] = sum[u << 1] + sum[u << 1 | 1];
		mx[u] = max (mx[u << 1], mx[u << 1 | 1]);
	}
	inline void push_down (int u, int l, int r) {
		if (inc[u] == -2e18) return ;
		inc[u << 1] = inc[u << 1 | 1] = inc[u];
		mx[u << 1] = mx[u << 1 | 1] = inc[u];
		int mid = l + r >> 1;
		sum[u << 1] = (mid - l + 1) * inc[u];
		sum[u << 1 | 1] = (r - mid) * inc[u];
		inc[u] = -2e18;
	}
	inline void build (int u, int l, int r) {
		inc[u] = -2e18;
		if (l == r) {
			sum[u] = mx[u] = val[l];
			return ; 
		}
		int mid = l + r >> 1;
		build (u << 1, l, mid);
		build (u << 1 | 1, mid + 1, r);
		push_up (u);
	}
	inline void update (int u, int l, int r, int x, int y, int v) {
		if (x <= l && r <= y) {
			sum[u] = (r - l + 1) * v;
			mx[u] = v;
			inc[u] = v;
			return ;
		}
		push_down (u, l, r);
		int mid = l + r >> 1;
		if (x <= mid) update (u << 1, l, mid, x, y, v);
		if (y > mid) update (u << 1 | 1, mid + 1, r, x, y, v);
		push_up (u);
	}
	inline int query_sum (int u, int l, int r, int x, int y) {
		if (x <= l && r <= y) return sum[u];
		push_down (u, l, r);
		int mid = l + r >> 1, ans = 0;
		if (x <= mid) ans += query_sum (u << 1, l, mid, x, y);
		if (y > mid) ans += query_sum (u << 1 | 1, mid + 1, r, x, y);
		return ans;
	}
	inline int query_max (int u, int l, int r, int x, int y) {
		if (x <= l && r <= y) return mx[u];
		push_down (u, l, r);
		int mid = l + r >> 1, ans = -2e18;
		if (x <= mid) ans = max (ans, query_max (u << 1, l, mid, x, y));
		if (y > mid) ans = max (ans, query_max (u << 1 | 1, mid + 1, r, x, y));
		return ans;
	}
} sg;
inline void update (int u, int w) {
	sg.update (1, 1, n, dfn[u], dfn[u], w);
}
inline int query_max (int u, int v) {
	int ans = -2e18, fu = top[u], fv = top[v];
	while (fu != fv) {
		if (depth[fu] >= depth[fv]) {
			ans = max (ans, sg.query_max (1, 1, n, dfn[fu], dfn[u]));
			u = fa[fu];
		}
		else {
			ans = max (ans, sg.query_max (1, 1, n, dfn[fv], dfn[v]));
			v = fa[fv]; 
		}
		fu = top[u];
		fv = top[v];
	}
	if (dfn[u] < dfn[v]) ans = max (ans, sg.query_max (1, 1, n, dfn[u], dfn[v]));
	else ans = max (ans, sg.query_max (1, 1, n, dfn[v], dfn[u]));
	return ans;
}
inline int query_sum (int u, int v) {
	int ans = 0, fu = top[u], fv = top[v];
	while (fu != fv) {
		if (depth[fu] >= depth[fv]) {
			ans += sg.query_sum (1, 1, n, dfn[fu], dfn[u]);
			u = fa[fu];
		}
		else {
			ans += sg.query_sum (1, 1, n, dfn[fv], dfn[v]);
			v = fa[fv]; 
		}
		fu = top[u];
		fv = top[v];
	}
	if (dfn[u] < dfn[v]) ans += sg.query_sum (1, 1, n, dfn[u], dfn[v]);
	else ans += sg.query_sum (1, 1, n, dfn[v], dfn[u]);
	return ans;
}
signed main () {
	scanf ("%lld", &n);
	for (int i = 1;i < n; ++ i) {
		int u, v;
		scanf ("%lld %lld", &u, &v);
		add_edge (u, v);
		add_edge (v, u);
	}
	depth[1] = 1;
	dfs1 (1);
	dfs2 (1, 1); 
	for (int i = 1;i <= n; ++ i) scanf ("%lld", &val[i]);
	sg.build (1, 1, n);
	int q;
	scanf ("%lld", &q);
	while (q --) {
		char op[10];
		scanf ("%s", op + 1);
		if (op[1] == 'C') {
			int x, y;
			scanf ("%lld %lld", &x, &y);
			update (x, y);
		}
		else if (op[2] == 'M') {
			int s, t;
			scanf ("%lld %lld", &s, &t);
			printf ("%lld\n", query_max (s, t));
		}
		else {
			int s, t;
			scanf ("%lld %lld", &s, &t);
			printf ("%lld\n", query_sum (s, t));
		}
	}
	return 0;
}
2023/3/19 21:38
加载中...