打个标记就能求出树链的并了。。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=200005;
const int base=2147483647;
int head[N],next[N<<1],list[N<<1],fa[N],deep[N],belong[N],size[N],in[N],out[N];
int l[N<<2],r[N<<2],sum[N<<2],ans[N<<2],tag1[N<<2],tag2[N<<2];
int n,m,cnt,dfn;
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
void dfs1(int x)
{
size[x]=1;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa[x])
{
fa[list[i]]=x;
deep[list[i]]=deep[x]+1;
dfs1(list[i]);
size[x]+=size[list[i]];
}
}
void dfs2(int x,int chain)
{
in[x]=++dfn; belong[x]=chain;
int k=0;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa[x]&&size[list[i]]>size[k])
k=list[i];
if (!k) {out[x]=dfn; return;}
dfs2(k,chain);
for (int i=head[x];i;i=next[i])
if (list[i]!=fa[x]&&list[i]!=k)
dfs2(list[i],list[i]);
out[x]=dfn;
}
inline void pushup(int k)
{
sum[k]=sum[k<<1]+sum[k<<1|1];
ans[k]=ans[k<<1]+ans[k<<1|1];
}
inline void pushdown(int k)
{
if (l[k]==r[k]) return;
if (tag1[k])
{
tag1[k<<1]+=tag1[k];
tag1[k<<1|1]+=tag1[k];
sum[k<<1]+=(r[k<<1]-l[k<<1]+1)*tag1[k];
sum[k<<1|1]+=(r[k<<1|1]-l[k<<1|1]+1)*tag1[k];
tag1[k]=0;
}
if (tag2[k]!=-1)
{
tag2[k<<1]=tag2[k<<1|1]=tag2[k];
ans[k<<1]=tag2[k]*sum[k<<1];
ans[k<<1|1]=tag2[k]*sum[k<<1|1];
tag2[k]=-1;
}
}
void build(int k,int x,int y)
{
l[k]=x; r[k]=y; tag2[k]=-1;
if (l[k]==r[k]) return;
int mid=l[k]+r[k]>>1;
build(k<<1,x,mid); build(k<<1|1,mid+1,y);
pushup(k);
}
void add(int k,int x,int y,int val)
{
if (l[k]==x&&r[k]==y)
{
tag1[k]+=val;
sum[k]+=(r[k]-l[k]+1)*val;
return;
}
pushdown(k);
int mid=l[k]+r[k]>>1;
if (y<=mid) add(k<<1,x,y,val);
else if (x>mid) add(k<<1|1,x,y,val);
else add(k<<1,x,mid,val),add(k<<1|1,mid+1,y,val);
pushup(k);
}
void modify(int k,int x,int y,int val)
{
if (tag2[k]==val) return;
if (l[k]==x&&r[k]==y)
{
tag2[k]=val;
ans[k]=sum[k]*val;
return;
}
pushdown(k);
int mid=l[k]+r[k]>>1;
if (y<=mid) modify(k<<1,x,y,val);
else if (x>mid) modify(k<<1|1,x,y,val);
else modify(k<<1,x,mid,val),modify(k<<1|1,mid+1,y,val);
pushup(k);
}
inline void solve(int x,int f,int val)
{
while (belong[x]!=belong[f])
{
modify(1,in[belong[x]],in[x],val);
x=fa[belong[x]];
}
modify(1,in[f],in[x],val);
}
int main()
{
n=read();
for (int i=1;i<n;i++)
{
int u=read(),v=read();
insert(u,v); insert(v,u);
}
dfs1(1); dfs2(1,1); build(1,1,n);
m=read();
while (m--)
{
int opt=read();
if (!opt)
{
int x=read(),y=read();
add(1,in[x],out[x],y);
}
else
{
int k=read();
for (int i=1;i<=k;i++)
{
int u=read(),v=read();
if (deep[u]<deep[v]) swap(u,v);
solve(u,v,1);
}
printf("%d\n",ans[1]&base);
modify(1,1,n,0);
}
}
return 0;
}