最近被狂虐。。。
题解没看懂,自己乱想了个DP,发现和标程的方法一模一样
然后发现自己完全不会写递推,只看懂了dfs1,dfs2尤其是q[]简直完全没懂
以前总以为这类DP很简单直到今天。。。。。。。。。。。。。。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
const int N=100010;
const LL mod=1000000007;
int n;
struct edge{int v,next;}e[N*2];
int head[N],k;
LL a[N],b[N];
LL f[N],g[N],p[N],q[N],inv[N];
inline void MOD(LL &x){if(x>=mod)x-=mod;else if(x<0)x+=mod;}
inline void adde(int u,int v){e[k]=(edge){v,head[u]};head[u]=k++;}
inline LL pow_mod(LL a,LL b,LL p){LL t=1;for(;b;b>>=1,a=a*a%p)if(b&1)t=t*a%p;return t;}
void dfs1(int u,int fa)
{
f[u]=1; g[u]=0;
INE(i,u)
{
int v=e[i].v; if(v==fa) continue;
dfs1(v,u);
f[u]=f[u]*(f[v]+1)%mod;
}
inv[u]=pow_mod(f[u]+1,mod-2,mod);
INE(i,u)
{
int v=e[i].v; if(v==fa) continue;
g[u]=g[u] + f[u] * inv[v] % mod * g[v] % mod; MOD(g[u]);
}
g[u]+=f[u]*b[u]%mod; MOD(g[u]);
//printf("f[%d]=%I64d g[%d]=%I64d\n",u,f[u],u,g[u]);
}
void dfs2(int u,int fa)
{
INE(i,u)
{
int v=e[i].v; if(v==fa) continue;
p[v]=(p[u] * inv[v] + 1) % mod * f[v] % mod; MOD(p[v]);
int tmp = p[u] * inv[v] % mod;
q[v] = (g[v] * (tmp + 1) % mod + (q[u] - tmp * g[v] % mod + mod) % mod * inv[v] % mod * f[v] % mod) % mod; MOD(q[v]);
//printf("p[%d]=%I64d q[%d]=%I64d\n",v,p[v],v,q[v]);
dfs2(v,u);
}
}
void input()
{
MS(head,-1);
n=read();
rep(i,1,n-1)
{
int u=read(),v=read();
adde(u,v); adde(v,u);
}
rep(i,1,n) a[i]=read();
rep(i,1,n) b[i]=read();
}
void solve()
{
dfs1(1,-1);
p[1]=f[1]; q[1]=g[1];
dfs2(1,-1);
LL ans=0;
rep(i,1,n) MOD(ans+=q[i]*a[i]%mod);
cout<<ans<<endl;
}
int main()
{
freopen("c.in","r",stdin); freopen("c.out","w",stdout);
input(),solve();
return 0;
}