路过的 dalao,帮忙看看吧,求。。
#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;
}