主席树 + 树剖 LCA WA 求调
查看原帖
主席树 + 树剖 LCA WA 求调
688783
SilverLi楼主2023/7/1 08:19
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define pi pair<int, int>
#define sum first
#define cnt second
const int N = 1e5 + 5;
int n, Q;
int dis[N], col[N], val[N];
struct edge { int v, col, val; };
vector<edge> g[N];
int root[N], fa[N], d[N];
int top[N], son[N], si[N];
struct node {
	int l, r;
	int sum, cnt;
}t[N];
int tot;
#define lu t[u].l
#define lv t[v].l
#define ru t[u].r
#define rv t[v].r
#define sumu t[u].sum
#define sumv t[v].sum
#define cntu t[u].cnt
#define cntv t[v].cnt
#define mid (l + r >> 1)
int build(int l, int r) {
	int u = ++tot;
	if (l == r)	return u;
	lu = build(l, mid);
	ru = build(mid + 1, r);
	return u;
}
int insert(int u, int l, int r, int p, int val) {
	int v = ++tot;
	t[v] = t[u];
	sumv += val, ++cntv;
	if (l == r)	return v;
	if (p < mid)
		lv = insert(lu, l, mid, p, val);
	else
		rv = insert(ru, mid + 1, r, p, val);
	return v;
}
pi ans(int u, int l, int r, int p) {
	if (l == r)	return {sumu, cntu};
	if (p < mid)
		return ans(lu, l, mid, p);
	else
		return ans(ru, mid + 1, r, p);
}
#define to g[u][l].v
#define cl g[u][l].col
#define vl g[u][l].val
void dfs(int u, int ft) {
	fa[u] = ft, si[u] = 1, d[u] = d[ft] + 1;
	for (int l = 0; l < g[u].size(); ++l)
		if (to != ft) {
			dfs(to, u);
			si[u] += si[to];
			col[to] = cl, val[to] = vl;
			dis[to] = dis[u] + vl;
			if (si[son[u]] < si[to])
				son[u] = to;
		}
}
void dfs2(int u, int deep) {
	top[u] = deep;
	root[u] = insert(root[fa[u]], 1, n, col[u], val[u]);
	if (!son[u])	return;
	dfs2(son[u], deep);
	for (int l = 0; l < g[u].size(); ++l)
		if (to != fa[u] && to != son[u])
			dfs2(to, to);
}
inline int LCA(int u, int v) {
	while (top[u] != top[v]) {
		if (d[top[u]] < d[top[v]])	swap(u, v);
		u = fa[top[u]];
	}
	if (d[u] > d[v])	swap(u, v);
	return u;
}
inline int get(int u, int co, int va) {
	pi res = ans(root[u], 1, n, co);
	return dis[u] - res.sum + res.cnt * va;
}
signed main() {
	cin >> n >> Q;
	for (int i = 1; i <= n; ++i) {
		int u, v, col, w;
		cin >> u >> v >> col >> w;
		g[u].push_back({v, col, w});
		g[v].push_back({u, col, w});
	}
	build(1, n);
	dfs(1, 0);
	dfs2(1, 1);
	while (Q--) {
		int co, va, u, v;
		cin >> co >> va >> u >> v;
		cout << get(u, co, va) + get(v, co, va) - 2 * get(LCA(u, v), co, va) << '\n';
	}
	return 0;
}
2023/7/1 08:19
加载中...