#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
#define int long long
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
int h[N],ne[N],e[N],idx;
int n,m;
int a[N];
int dep[N],fa[N],top[N];
int sz[N];
int son[N];
int id[N];
int nw[N];
int cnt;
struct node
{
int l;
int r;
int tag;
int sum;
}tr[N<<2];
void add(int a,int b)
{
ne[idx]=h[a],e[idx]=b,h[a]=idx++;
}
void dfs1(int u,int f,int depth)
{
dep[u]=depth,fa[u]=f,sz[u]=1;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(j==f) continue;
dfs1(j,u,depth+1);
sz[u]+=sz[j];
if(sz[son[u]]<sz[j]) son[u]=j;
}
}
void dfs2(int u,int t)
{
id[u]=++cnt;
nw[cnt]=a[u];
top[u]=t;
if(!son[u]) return;
dfs2(son[u],t);
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(j!=fa[u]&&j!=son[u])
dfs2(j,j);
}
}
void pushup(int u)
{
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void pushdown(int u)
{
if(tr[u].tag)
{
tr[u<<1].tag+=tr[u].tag;
tr[u<<1|1].tag+=tr[u].tag;
tr[u<<1].sum+=tr[u].tag*(tr[u<<1].r-tr[u<<1].l+1);
tr[u<<1|1].sum+=tr[u].tag*(tr[u<<1|1].r-tr[u<<1|1].l+1);
tr[u].tag=0;
}
}
void build(int u,int l,int r)
{
tr[u]={l,r};
if(l==r)
{
tr[u].sum=nw[l];
return;
}
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
void modify(int u,int l,int r,int k)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
tr[u].sum+=k*(tr[u].r-tr[u].l+1);
tr[u].tag+=k;
return;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) modify(u<<1,l,r,k);
if(r>mid) modify(u<<1|1,l,r,k);
pushup(u);
}
int query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
return tr[u].sum;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
int ans=0;
if(l<=mid) ans+=query(u<<1,l,r);
if(r>mid) ans+=query(u<<1|1,l,r);
return ans;
}
void modify_tree(int u,int k)
{
modify(1,id[u],id[u]+sz[u]-1,k);
}
int query_tree(int u)
{
return query(1,id[u],id[u]+sz[u]-1);
}
void modify_path(int u,int v,int k)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
modify(1,id[top[u]],id[u],k);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
modify(1,id[v],id[u],k);
}
int query_path(int u,int v)
{
int res=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=query(1,id[top[u]],id[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
res+=query(1,id[v],id[u]);
return res;
}
void solve()
{
scanf("%lld",&n);
memset(h,-1,sizeof(h));
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=1;i<n;i++)
{
int a,b;
scanf("%lld%lld",&a,&b);
add(a,b);
add(b,a);
}
dfs1(1,-1,1);
dfs2(1,1);//当前点,当前点所在重链的顶点
build(1,1,n);
scanf("%lld",&m);
for(int i=1;i<=m;i++)
{
int op,u,v,k;
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld%lld",&u,&v,&k);
modify_path(u,v,k);
}else if(op==2)
{
scanf("%lld%lld",&u,&k);
modify_tree(u,k);
}else if(op==3)
{
scanf("%lld%lld",&u,&v);
cout<<query_path(u,v)<<endl;
}else{
scanf("%lld",&u);
cout<<query_tree(u)<<endl;
}
}
}
signed main() {
//#ifdef LOCAL
//freopen("data.in.txt","r",stdin);
//freopen("data.out.txt","w",stdout);
//#endif
int __ = 1;
//cin>>__;
while (__--)
{
solve();
}
return 0;
}
07-22
318
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交