RT,代码是直接用自己在隔壁板子题的AC代码改的,但是全WA。。。
#include <bits/stdc++.h>
#define in inline
#define rint register int
#define r(a) runtimerror(a)
#define w(a) wronganswer(a)
#define wl(a) wronganswer(a);putchar('\n')
#define ws(a) wronganswer(a);putchar(' ')
using namespace std;
typedef long long ll;
ll a[100010];
int n,m,u,v,opt,x,y,tot,cnt,head[100010],size[100010],son[100010],dep[100010],fa[100010],nid[100010],top[100010],newn[100010];
template <typename t> void wronganswer(t a){
if(a<0) putchar('-'),a=-a;
if(a>9) wronganswer(a/10);
putchar(a%10^48);
}
template <typename t> in void runtimerror(t &a){
char ch=getchar();
t x=1,f=0;
while(!isdigit(ch)){
if(ch=='-') x=-1;
ch=getchar();
}
while(isdigit(ch)){
f=(f<<3)+(f<<1)+(ch^48);
ch=getchar();
}
a=x*f;
}
struct Edge{
int to,nex;
}edge[200010];
in void add_edge(int from,int to){
edge[++tot]={to,head[from]};
head[from]=tot;
}
void dfs1(int id,int fat,int dp){
size[id]=1,dep[id]=dp,fa[id]=fat;
for(rint i=head[id];i;i=edge[i].nex){
if(edge[i].to==fat) continue;
dfs1(edge[i].to,id,dp+1);
size[id]+=size[edge[i].to];
if(size[edge[i].to]>size[son[id]]) son[id]=edge[i].to;
}
}
void dfs2(int id,int t){
top[id]=t,nid[id]=++cnt,newn[cnt]=a[id];
if(!son[id]) return;
dfs2(son[id],t);
for(rint i=head[id];i;i=edge[i].nex){
if(edge[i].to==fa[id]||edge[i].to==son[id]) continue;
dfs2(edge[i].to,edge[i].to);
}
}
struct segment_tree{
struct segment{
int l,r;
ll sum,tag;
}s[400010];
in void pushup(int id){
s[id].sum=s[id<<1].sum+s[id<<1|1].sum;
}
in void pushdown(int id){
if(!s[id].tag) return;
segment &rt=s[id],&l=s[id<<1],&r=s[id<<1|1];
l.tag+=rt.tag,l.sum+=rt.tag*(l.r-l.l+1);
r.tag+=rt.tag,r.sum+=rt.tag*(r.r-r.l+1);
rt.tag=0;
}
void build(int id,int l,int r){
if(l==r){
s[id]={l,r,newn[l],0};
return;
}
s[id]={l,r};
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
pushup(id);
}
void modify(int id,int l,int r,ll val){
if(s[id].l>=l&&s[id].r<=r){
s[id].tag+=val;
s[id].sum+=(s[id].r-s[id].l+1)*val;
return;
}
pushdown(id);
int mid=s[id].l+s[id].r>>1;
if(mid>=l) modify(id<<1,l,r,val);
if(mid<r) modify(id<<1|1,l,r,val);
pushup(id);
}
void modify_node(int id,int target,ll val){
if(s[id].l==s[id].r&&s[id].l==target){
s[id].sum+=val;
return;
}
pushdown(id);
int mid=s[id].l+s[id].r>>1;
if(mid>=target) modify_node(id<<1,target,val);
else modify_node(id<<1|1,target,val);
pushup(id);
}
ll query(int id,int l,int r){
if(s[id].l>=l&&s[id].r<=r) return s[id].sum;
pushdown(id);
int mid=s[id].l+s[id].r>>1;
ll ans=0;
if(mid>=l) ans+=query(id<<1,l,r);
if(mid<r) ans+=query(id<<1|1,l,r);
return ans;
}
in ll query_path(int u,int v){
ll ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=query(1,nid[top[u]],nid[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
ans+=query(1,nid[v],nid[u]);
return ans;
}
in void modify_tree(int id,ll val){
modify(1,nid[id],nid[id]+size[id]-1,val);
}
}t;
signed main(){
r(n),r(m);
for(rint i=1;i<=n;i++){
r(a[i]);
}
for(rint i=1;i<n;i++){
r(u),r(v);
add_edge(u,v);
add_edge(v,u);
}
dfs1(1,0,1);
dfs2(1,1);
t.build(1,1,n);
while(m--){
r(opt);
switch(opt){
case 1:
r(x),r(y);
t.modify_node(1,x,y);
break;
case 2:
r(x),r(y);
t.modify_tree(x,y);
break;
case 3:
r(x);
wl(t.query_path(1,x));
break;
}
}
return 0;
}