洛谷树求助,调了几天了
  • 板块P3401 洛谷树
  • 楼主__xzm__
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/10/21 19:44
  • 上次更新2023/10/27 06:38:16
查看原帖
洛谷树求助,调了几天了
540333
__xzm__楼主2022/10/21 19:44

路过的 dalaodalao,帮忙看看吧,求。。

#include <bits/stdc++.h>

#define root 1, n, 1
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1

using namespace std;

const int N = 30010, M = 60010;

int head[N], nxt[M], to[M], w[M], idx;

void init()
{
	idx = 0;
	memset(head, -1, sizeof head);
}

void add(int a, int b, int c)
{
	nxt[idx] = head[a], head[a] = idx;
	to[idx] = b, w[idx] = c, idx++;
}

int n, m, wxor[N];
int fa[N], son[N], sz[N];
int id[N], nw[N], tot;
int dep[N], tp[N];
int weight[N];
struct node
{
	int l, r, tag, len, _w, cnt[10];
	
	void init(int k, int x)
	{
		l = r = k, tag = -1;
		len = 1, _w = weight[k];
		for (int i = 0; i < 10; i++)
			cnt[i] = (x >> i & 1);
	}
	
	void color(int v, int w)
	{
		tag = w, _w = v;
		for (int i = 0; i < 10; i++)
			if ((v^w) >> i & 1) cnt[i] = len-cnt[i];
	}
	
	long long sum()
	{
		long long res = 0;
		for (int i = 0; i < 10; i++)
			res += (1ll<<i)*cnt[i]*(len-cnt[i]);
		
		return res;
	}
} z[N<<2];

void dfs1(int x, int p)
{
	fa[x] = p, sz[x] = 1, dep[x] = dep[p]+1;
	for (int i = head[x]; ~i; i = nxt[i])
	{
		if (to[i] == p) continue;
		
		dfs1(to[i], x);
		sz[x] += sz[to[i]];
		if (sz[to[i]] > sz[son[x]]) son[x] = to[i];
	}
}

void dfs2(int x, int t, int wei)
{
	wxor[x] = wxor[fa[x]]^wei;
	id[x] = ++tot, nw[tot] = wxor[x], tp[x] = t;
	weight[tot] = wei;
	
	if (!son[x]) return;
	
	for (int i = head[x]; ~i; i = nxt[i])
		if (to[i] == son[x])
		{
			dfs2(son[x], t, w[i]);
			break;
		}
	
	for (int i = head[x]; ~i; i = nxt[i])
	{
		if (to[i] == fa[x] || to[i] == son[x]) continue;
		dfs2(to[i], to[i], w[i]);
	}
}

node operator + (const node &l, const node &r)
{
	node res;
	res.l = l.l, res.r = r.r;
	res.tag = -1, res.len = l.len+r.len;
	res._w = 0;
	
	for (int i = 0; i < 10; i++)
		res.cnt[i] = l.cnt[i]+r.cnt[i];
	
	return res;
}

void pushdown(int rt)
{
	if (z[rt].tag > -1)
	{
		z[rt<<1].color(z[rt].tag, z[rt]._w);
		z[rt<<1|1].color(z[rt].tag, z[rt]._w);
		z[rt].tag = -1;
	}
}

void build(int l, int r, int rt)
{
	if (l == r)
	{
		z[rt].init(l, nw[l]);
		return;
	}
	
	int mid = (l+r)>>1;
	build(lson), build(rson);
	
	z[rt] = z[rt<<1]+z[rt<<1|1];
}

void modify(int l, int r, int rt, int nl, int nr, int v, int w)
{
	if (nl <= l && r <= nr)
	{
		z[rt].color(v, w);
		return;
	}
	
	pushdown(rt);
	
	int mid = (l+r)>>1;
	if (nl <= mid) modify(lson, nl, nr, v, w);
	if (nr > mid) modify(rson, nl, nr, v, w);
	
	z[rt] = z[rt<<1]+z[rt<<1|1];
}

node query(int l, int r, int rt, int nl, int nr)
{
	if (nl <= l && r <= nr) return z[rt];
	
	pushdown(rt);
	
	int mid = (l+r)>>1;
	if (nr <= mid) return query(lson, nl, nr);
	if (nl > mid) return query(rson, nl, nr);
	return query(lson, nl, nr)+query(rson, nl, nr);
}

long long query_path(int u, int v)
{
	node res = {0, 0, 0, 0, 0, {0}};
	while (tp[u] != tp[v])
	{
		if (dep[tp[u]] < dep[tp[v]]) swap(u, v);
		
		if (!res.l) res = query(root, id[tp[u]], id[u]);
		else res = res+query(root, id[tp[u]], id[u]);
//		cout << res.sum() << endl;
//		puts("--------------fengexian----------");
		u = fa[tp[u]];
	}
	
	if (dep[u] < dep[v]) swap(u, v);
	if (!res.l) res = query(root, id[v], id[u]);
	else res = res+query(root, id[v], id[u]);
	
	return res.sum();
}

void modify_tree(int u, int v, int w)
{
	if (dep[u] > dep[v]) swap(u, v);
	modify(root, id[v], id[v]+sz[v]-1, weight[id[v]], w);
	weight[id[v]] = w;
}

int main()
{
	init();
	
	scanf("%d%d", &n, &m);
	
	for (int i = 1; i < n; i++)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		
		add(a, b, c);
		add(b, a, c);
	}
	
	dfs1(1, 0);
	dfs2(1, 1, 0);
	build(root);
	
	while (m--)
	{
		int op, u, v, w;
		scanf("%d%d%d", &op, &u, &v);
		
		if (op == 1)
			printf("%lld\n", query_path(u, v));
		else
		{
			scanf("%d", &w);
			modify_tree(u, v, w);
		}
	}
	
	return 0;
}
2022/10/21 19:44
加载中...