题目大意
给定一课
N
个节点数,有
令
对于每一个节点
O(m(n−−√+logn))
#include<cstdio>
#include<cmath>
#define N 50005
#define M 235
int up[N][M],a[N],b[N],c[N],n,en,h[N],x,y,f[N],li[N],l,block,sz[N],son[N],top[N],dep[N],nx[N][M];
struct edge{int next,x;}e[N*2];
inline void ins(int a,int b){e[++en].x=b;e[en].next=h[a];h[a]=en;}
inline void read(int &x)
{
char ch=C();x=0;int f=1;
for(;ch>'9'||ch<'0';ch=C())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',ch=C());x*=f;
}
void dfs1(int x)
{
sz[x]=1;li[++l]=x;dep[x]=dep[f[x]]+1;
for(int i=h[x];i;i=e[i].next)
if(e[i].x!=f[x])
{
f[e[i].x]=x;dfs1(e[i].x);
if(sz[e[i].x]>sz[son[x]])son[x]=e[i].x;
sz[x]+=sz[e[i].x];
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
if(son[x])dfs2(son[x],tp);
for(int i=h[x];i;i=e[i].next)
if(e[i].x!=f[x]&&e[i].x!=son[x]) dfs2(e[i].x,e[i].x);
}
inline int father(int x,int y)
{
while(y>=block) x=nx[x][block],y-=block;
return nx[x][y];
}
inline int calc(int a,int b,int c)
{
int x=a,y=b,ans=0,l=0,s,lca;
while(top[x]!=top[y])
if(dep[top[x]]<dep[top[y]]) y=f[top[y]]; else x=f[top[x]];
if(dep[x]>dep[y]) lca=y;else lca=x;
if(dep[a]+dep[b]-2*dep[lca]<=c) return up[a][0]+up[b][0];
if(c<=block)
{
if((dep[a]+dep[b]-2*dep[lca])%c==0) ans-=up[b][0];
if(lca==a) return ans+up[nx[b][(dep[b]-dep[a])%c]][c]-up[nx[a][c]][c]+up[b][0];
if(lca==b) return ans+up[a][c]-up[father(a,(dep[a]-dep[b])/c*c+c)][c]+up[b][0];
ans+=up[a][c]-up[father(a,(dep[a]-dep[lca])/c*c+c)][c];
ans+=up[father(b,(dep[b]+dep[a]-2*dep[lca])%c)][c]-up[father(lca,(dep[a]-dep[lca])%c)][c]+up[b][0];
return ans;
}
if(lca==a)
{
ans=up[b][0];
if((dep[b]+dep[a]-2*dep[lca])%c==0) ans-=up[b][0];
b=father(b,(dep[b]-dep[a])%c);
while(dep[b]>=dep[a]) ans+=up[b][0],b=father(b,c);
return ans;
}
if(lca==b)
{
if((dep[b]+dep[a]-2*dep[lca])%c==0) ans-=up[b][0];
while(dep[a]>=dep[b]) ans+=up[a][0],a=father(a,c);
return ans+up[b][0];
}
ans=up[b][0];
if((dep[b]+dep[a]-2*dep[lca])%c==0) ans-=up[b][0];
if((dep[a]-dep[lca])%c==0) ans-=up[lca][0];
b=father(b,(dep[b]+dep[a]-dep[lca]*2)%c);
while(dep[a]>=dep[lca])ans+=up[a][0],a=father(a,c);
while(dep[b]>=dep[lca])ans+=up[b][0],b=father(b,c);
return ans;
}
int main()
{
read(n);
for(int i=1;i<=n;i++) read(a[i]),up[i][0]=a[i],nx[i][0]=i;
for(int i=1;i<n;i++) read(x),read(y),ins(x,y),ins(y,x);
for(int i=1;i<=n;i++) read(b[i]);
for(int i=1;i<n;i++) read(c[i]);
dfs1(1);dfs2(1,1);block=(int)sqrt(n);
for(int i=1;i<=l;i++)
for(int j=1;j<=block;j++)
nx[li[i]][j]=nx[f[li[i]]][j-1],up[li[i]][j]=up[nx[li[i]][j]][j]+a[li[i]];
for(int i=1;i<n;i++)
printf("%d\n",calc(b[i],b[i+1],c[i]));
return 0;
}