不加懒惰标记就T,加了WA了.
#include<bits/stdc++.h>
#define N 30010
#define ls (i<<1)
#define rs (i<<1|1)
#define LL long long
using namespace std;
int n,q;
int read()
{
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct Edge{int v,w,nxt;}e[N<<1];
int size,head[N];
void add(int u,int v,int w){e[++size].v=v;e[size].nxt=head[u];e[size].w=w;head[u]=size;}
int rev[N],seg[N],sze[N],val[N],dep[N],fa[N],son[N],top[N],cnt,lazy[N];
void dfs1(int u,int father)
{
sze[u]=1;dep[u]=dep[father]+1;fa[u]=father;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(v==father)continue;
val[v]=val[u]^e[i].w;
dfs1(v,u);
sze[u]+=sze[v];
if(sze[v]>sze[son[u]])son[u]=v;
}
}
void dfs2(int u)
{
if(son[u])
{
int v=son[u];
top[v]=top[u];
rev[v]=++cnt;
seg[cnt]=v;
dfs2(v);
}
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(!top[v])
{
top[v]=v;
rev[v]=++cnt;
seg[cnt]=v;
dfs2(v);
}
}
}
struct Node{
int num0[15],num1[15];
Node operator +(const Node &q)const
{
Node res;
for(int i=0;i<11;++i)
{
res.num0[i]=num0[i]+q.num0[i];
res.num1[i]=num1[i]+q.num1[i];
}
return res;
}
void clear()
{
memset(num0,0,sizeof(num0));
memset(num1,0,sizeof(num1));
}
}sum[N<<2];
void change(int pos,int k)
{
for(int i=0;i<11;++i)
{
if(k&(1<<i))swap(sum[pos].num0[i],sum[pos].num1[i]);
}
lazy[pos]^=k;
}
void pushdown(int i)
{
if(lazy[i]==0)return;
change(ls,lazy[i]);
change(rs,lazy[i]);
lazy[i]=0;
}
Node query(int i,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return sum[i];
int mid=(l+r)>>1;
Node res;
res.clear();
pushdown(i);
if(x<=mid)res=res+query(ls,l,mid,x,y);
if(y>mid)res=res+query(rs,mid+1,r,x,y);
return res;
}
void update(int i,int l,int r,int x,int y,int k)
{
if(x<=l&&r<=y)
{
change(i,k);
return ;
}
pushdown(i);
int mid=(l+r)>>1;
if(x<=mid)update(ls,l,mid,x,y,k);
if(y>mid)update(rs,mid+1,r,x,y,k);
sum[i]=sum[ls]+sum[rs];
}
LL QUERY(int x,int y)
{
int fx=top[x],fy=top[y];
Node fuck;fuck.clear();
while(fx!=fy)
{
if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y);
fuck=fuck+query(1,1,n,rev[fx],rev[x]);
x=fa[fx];fx=top[x];
}
if(dep[x]<dep[y])swap(x,y);
fuck=fuck+query(1,1,n,rev[y],rev[x]);
LL res=0;
for(int i=0;i<11;++i)res=res+1ll*fuck.num0[i]*fuck.num1[i]*(1LL<<i);
return res;
}
void build(int i,int l,int r)
{
if(l==r)
{
int x=seg[l];
for(int j=0;j<11;++j)
{
if(val[x]&(1<<j))sum[i].num1[j]=1;
else sum[i].num0[j]=1;
}
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
sum[i]=sum[ls]+sum[rs];
}
int main()
{
n=read();q=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read(),w=read();
add(u,v,w);
add(v,u,w);
}
dfs1(1,0);
++cnt;rev[1]=1;seg[1]=1;top[1]=1;
dfs2(1);
build(1,1,n);
int opt,u,v,w,lat;
while(q--)
{
opt=read();u=read();v=read();
if(opt==1)printf("%lld\n",QUERY(u,v));
else
{
w=read();
if(dep[u]<dep[v])swap(u,v);
for(int i=head[u];i;i=e[i].nxt)
{
if(e[i].v==v)
{
lat=e[i].w;
e[i].w=w;
break;
}
}
update(1,1,n,rev[u],rev[u]+sze[u]-1,w^lat);
}
}
return 0;
}